Erlang explained: Selective receive
If you worked with Erlang you've probably heard about selective receive. But do you actually know how it works? I want to post here an excerpt from Joe Armstrong's book Programming Erlang where he explains how it works exactly (Section 8.6, p.153):
receive
Pattern1 [when Guard1] -> Expressions1;
Pattern2 [when Guard2] -> Expressions2;
...
after
Time -> ExpressionTimeout
end
When we enter a receive statement, we start a timer (but only if an after section is present in the expression).
Take the first message in the mailbox and try to match it against Pattern1, Pattern2, and so on. If the match succeeds, the message is removed from the mailbox, and the expressions following the pattern are evaluated.
If none of the patterns in the receive statement matches the first message in the mailbox, then the first message is removed from the mailbox and put into a "save queue." The second message in the mailbox is then tried. This procedure is repeated until a matching message is found or until all the messages in the mailbox have been examined.
If none of the messages in the mailbox matches, then the process is suspended and will be rescheduled for execution the next time a new message is put in the mailbox. Note that when a new message arrives, the messages in the save queue are not rematched; only the new message is matched.
As soon as a message has been matched, then all messages that have been put into the save queue are reentered into the mailbox in the order in which they arrived at the process. If a timer was set, it is cleared.
If the timer elapses when we are waiting for a message, then evaluate the expressions ExpressionsTimeout and put any saved messages back into the mailbox in the order in which they arrived at the process.
Did you notice the concept of "save queue"? That's what many people are not aware of. Let's play with various scenarios and see the mailbox and save queue in action.
The first scenario is simple, nothing to test there in regards to mailbox. The second one is also straightforward:
1> self() ! a.
a
2> process_info(self()).
...
{message_queue_len,1},
{messages,[a]},
...
3> receive a -> 1; b -> 2 end.
1
4> process_info(self()).
...
{message_queue_len,0},
{messages,[]},
...
You send a message to the shell, you see it in the process mailbox, then you receive it by matching, after which the queue is empty. Standard queue behaviour.
Now let's test scenario 3,5:
1> self() ! c, self() ! d, self() ! a.
a
2> process_info(self()).
...
{message_queue_len,3},
{messages,[c,d,a]},
...
3> receive a -> 1; b -> 2 end.
1
4> process_info(self()).
...
{message_queue_len,2},
{messages,[c,d]},
...
Again, no surprises. Actually, this example demonstrates what people think when they hear about selective receive. Unfortunately we don't see what happened internally between lines 3 and 4. We are going to investigate it now by testing scenario 3,4.
This time start the shell in distributed mode so that we can connect to it later from the remote shell.
(foo@bar)1> register(shell, self()).
true
(foo@bar)2> shell ! c, shell ! d.
d
(foo@bar)3> process_info(whereis(shell)).
...
{current_function,{erl_eval,do_apply,5}},
...
{message_queue_len,2},
{messages,[c,d]},
...
(foo@bar)4> receive a -> 1; b -> 2 end.
At this moment the shell is suspended - we are exactly at step 4. Go to remote shell, and type the following:
(foo@bar)1> process_info(whereis(shell)).
...
{current_function,{erl_eval,receive_clauses,6}},
...
{message_queue_len,0},
{messages,[]},
...
That's interesting: no messages in the mailbox. As Joe said, they are in the save queue. Now send a matching message:
(foo@bar)2> shell ! a.
a
Go back to initial shell, which should be resumed now, and check the mailbox again:
1
(foo@bar)5> process_info(whereis(shell)).
...
{current_function,{erl_eval,do_apply,5}},
...
{message_queue_len,2},
{messages,[c,d]},
...
That's what we saw in the previous test, but now you know what happens behind the scenes: messages are moved from the mailbox to the save queue and then back to the mailbox after the matching message arrives.
Now you should understand better how selective receive works. Next time you explore your Erlang process, keep in mind the save queue and disappearing and reappearing messages.
相关推荐
queue.cpp -- function definitions for the Array implementation of a Queue
当更新SVN时,出现Failed to run the WC DB work queue
1.将sqlite3.exe放到.svn的同级目录 2.启动cmd执行sqlite3 .svn/wc.db 3. "select * from work_queue"; 4. delete from work_queue; 5.svn目录下右键:TortoiseSVN->Clean up
CH341SER_WIN7适合win764系统
THis is an example source code for the queue implemented by systemc.
C语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言头文件 QUEUE.HC语言...
The 80x86 MOV Instruction 4.8 - Some Final Comments on the MOV Instructions <br>4.9 Laboratory Exercises 4.9.1 The UCR Standard Library for 80x86 Assembly Language Programmers 4.9.2 ...
This letter presents the recursive formulas of the moments of queue length for the M/M/1 queue and M/M/1/B queue, respectively. The higher moments of queue length are important for optimization ...
We provide plenty of examples along the way to help you understand each concept. You will get the also get a clear picture of reactive programming, binary searches, sorting, search trees, undirected ...
A very good book! You can loaddown then take it back home and Study!
Implementation-of-the-Queue-Interface-master.rar
Apache Hadoop YARN is the modern distributed operating system for big data applications....And you’ll leave with all the knowledge of how to upgrade painlessly from 2.x to 3.x to get all the benefits.
On the Spark Streaming front, two major features have been added: mapWithState to maintain state across batches and using back pressure to throttle the input rate in case of queue buildup.2 In ...
一个很不错的消息中间件的源码,使用C/C++实现,目前版本为8.0版本,强烈推荐!
1. Message Queue的角色 在你的Android程序里,新诞生一个线程,或称执行(Thread)时,并不会自动建立其Message Loop。 Android里并没有Global的Message Queue数据结构,例如,不同APK里的对象不能透过...
Queue-Queue-Queue
The availability of drivers that support the features of the specification will simplify the process of developing Windows appli¬cation programs that in-corporate absolute coordinate input, and ...
Can't locate ThreadQueue.pm
an update formula that allows the expression of the deviation matrix of a continuous-time Markov process with denumerable state space having generator matrix through a continuous-time Markov process ...
Queue与Topic的比较,学习JMS和activemq必须看的资料之一