Check if the mailbox is empty? in erlang

I need to make a check that returns true or false, depending on whether the current process has any message in its mailbox in erlang.

+5
source share
3 answers

You can use BIF process_info/2to access process information, including a message queue. So

process_info(self(), message_queue_len) => {message_queue_len,Length}

and

process_info(self(), messages) => {messages,MessageList}

The second is ineffective if there are many messages in the queue, since a list is created for each call (although not from messages, of course). There are many interesting things you can learn about the process. There are no restrictions on which process you can get information on, you can do it for any process.

+9
source

0 receive. , , false.

1> receive _ -> true  
1> after 0 ->
1> false
1> end.
empty

, .

erlang:process_info, , , .

6> {message_queue_len, QueueLen} = erlang:process_info(self(), message_queue_len).
{message_queue_len,0}
7> QueueLen.
0

:

16> HasMessages = fun(Pid) ->                                           
16>     element(2, erlang:process_info(Pid, message_queue_len)) > 0     
16> end.
#Fun<erl_eval.6.80247286>
17> HasMessages(self()).                                                                      
false
18> self() ! test.
test
19> HasMessages(self()).
true
+4

, .

! , :

{module, hasMsg}.
{exports, [{module_info,0},{module_info,1},{hasMsg,0},{peekMsg,1},{lastMsg,1}]}.
{attributes, []}.
{labels, 17}.

{function, hasMsg, 0, 2}.
    {label,1}.
        {func_info,{atom,hasMsg},{atom,hasMsg},0}.
    {label,2}.
        {loop_rec,{f,4},{x,0}}.
        {move,{atom,true},{x,0}}.
        return.
    {label,3}.
        {loop_rec_end,{f,2}}.
    {label,4}.
        timeout.
        {move,{atom,false},{x,0}}.
        return.

{function, peekMsg, 1, 6}.
    {label,5}.
        {func_info,{atom,hasMsg},{atom,peekMsg},1}.
    {label,6}.
        {loop_rec,{f,8},{x,0}}.
        return.
    {label,7}.
        {loop_rec_end,{f,6}}.
    {label,8}.
        timeout.
        return.

{function, lastMsg, 1, 10}.
    {label,9}.
        {func_info,{atom,hasMsg},{atom,lastMsg},1}.
    {label,10}.
        {loop_rec,{f,12},{x,0}}.
        {test,is_eq_exact,{f,11},[]}.
    {label,11}.
        {loop_rec_end,{f,10}}.
    {label,12}.
        timeout.
        return.

{function, module_info, 0, 14}.
    {label,13}.
        {func_info,{atom,hasMsg},{atom,module_info},0}.
    {label,14}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.

{function, module_info, 1, 16}.
    {label,15}.
        {func_info,{atom,hasMsg},{atom,module_info},1}.
    {label,16}.
        {move,{x,0},{x,1}}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.

: erlc +from_asm hasMsg.S.

hasMsg :

  • hasMsg/0 , .
  • peekMsg/1 . , .
  • lastMsg/1 . , .
+1

All Articles