2
votes

Say I have an Erlang process whose message queue currently looks like this:

msg1
msg2
{timeout, Ref1, some_atom}
msg3
msg4

What the message queue will look like if I do:

receive
    {timeout, Ref1, some_atom} ->
        0
after 0
    false
end
1

1 Answers

6
votes

You can try this in the shell to find out:

1> Pid = spawn(fun F() -> receive start -> receive {timeout, Ref1, some_atom} -> F() after 0 -> ok end end end).
<0.47.0>
2> Pid ! msg1.
msg1
3> Pid ! msg2.
msg2
4> Pid ! {timeout, erlang:make_ref(), some_atom}.
{timeout,#Ref<0.0.8.133>,some_atom}
5> Pid ! msg3.
msg3
6> Pid ! msg4.
msg4
7> erlang:process_info(Pid, messages).
{messages,[msg1,msg2,
           {timeout,#Ref<0.0.8.133>,some_atom},
           msg3,msg4]}
8> Pid ! start.
start
9> erlang:process_info(Pid, messages).
{messages,[msg1,msg2,msg3,msg4]}
  • Command 1 creates a process Pid waiting to receive a start atom, after which it performs the receive you specified in your question.
  • Commands 2-6 create the message queue in Pid matching your question.
  • Command 7 verifies that the Pid message queue is what we expect.
  • Command 8 sends the start atom to cause Pid to execute the receive you specified in your question, and then go back and wait for another start message.
  • Command 9 checks the Pid message queue again. As we can see, the code received the {timeout, Ref1, some_atom} tuple and left msg1 and similar atoms in the queue.

The results of command 9 are exactly what we expect, due to Erlang's selective receive capability, which causes it to look through the message queue to find the first match when receiving messages. If no messages matched in this case, the after 0 clause would instead execute, which in this code would mean the spawned function would finish and Pid would exit.