I need to do a check, which returns true or false, depending on whether the current process has any message in its mailbox in erlang.
You can use the process_info/2
BIF to access process information including the message queue. So
process_info(self(), message_queue_len) => {message_queue_len,Length}
and
process_info(self(), messages) => {messages,MessageList}
The second one is inefficient if there are many messages in the queue as the list is created for each call (though not the messages of course). There are many interesting things you can find out about a process. There are no restrictions on which process you can get info, you can do it for any process.
You should be able to use 0
for the receive
timeout. In the example below, it will try to get a message out of the queue, if there are none in there it will return the atom false
.
1> receive _ -> true
1> after 0 ->
1> false
1> end.
empty
Be warning this will consume a message.
One other way would be to use erlang:process_info
but this is supposedly only for debugging.
6> {message_queue_len, QueueLen} = erlang:process_info(self(), message_queue_len).
{message_queue_len,0}
7> QueueLen.
0
Altogether now:
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
Internally there are means to test if there is a message in the process mailbox.
But beware! I don't think Erlang is meant to be used like that:
{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}}.
Compile: erlc +from_asm hasMsg.S
.
The module hasMsg
contains:
hasMsg/0
returns a boolean whether there are messages in the mailbox.peekMsg/1
returns the oldest message without removing it. Returns its argument, if the mailbox is empty.lastMsg/1
returns the newest message without removing it. Returns its argument, if the mailbox is empty.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With