Erlang explained: Selective receive
来源:互联网 发布:c语言开根号写函数 编辑:程序博客网 时间:2024/06/06 08:45
原文地址:http://ndpar.blogspot.de/2010/11/erlang-explained-selective-receive.html
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 -> ExpressionTimeoutend
- 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.a2> process_info(self()). ... {message_queue_len,1}, {messages,[a]}, ...3> receive a -> 1; b -> 2 end.14> 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.a2> process_info(self()). ... {message_queue_len,3}, {messages,[c,d,a]}, ...3> receive a -> 1; b -> 2 end.14> 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.
- Erlang explained: Selective receive
- erlang msg selective receive
- [Erlang 0100] make_ref 与 Selective Receive
- erlang 中 receive 代码块
- receive
- erlang 怎么和 c/c++ 发送消息,交互,(send ,receive msg message)
- selective repeat
- Selective Search
- Aggregation explained
- dmesg explained
- Unicode Explained
- LZ4 explained
- SCORM Explained
- xss explained
- Erlang
- Erlang
- Erlang
- erlang
- C#最小时到托盘\点托盘图标正常显示
- 分类模型的性能评估——以SAS Logistic回归为例(1): 混淆矩阵
- 第八周任务-上机实战
- 如何找回Oracle中system,sys用户的密码 .
- 《ARM与Linux些许问题》第三章:Linux如何从用户态进入内核态
- Erlang explained: Selective receive
- 调查称66万人民币可购房移居德国是误导-移居-移民-德国
- 求两个数的整除余数
- oracle基本操作 oracle常用命令
- android intent隐式调用之一个应用程序启动另一个应用程序
- 我的第七个c++上机报告(%/0时的撞错)
- 重载(overload)、覆盖(override)与隐藏
- C#禁用关闭按钮(变灰)
- 计算n!中结尾零的个数——上海先锋商泰面试归来