原文地址: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 fromJoe Armstrong's bookProgramming
Erlangwhere he explains how it worksexactly(Section
8.6, p.153):
receive
Pattern1 [when Guard1] -> Expressions1;
Pattern2 [when Guard2] -> Expressions2;
...
after
Time -> ExpressionTimeout
end
- When we enter areceivestatement, we start a timer (but only if anaftersection is present in the expression).
- Take the first message in the mailbox and try to match it againstPattern1,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 thereceivestatement matches the first message in the mailbox, then the first message is removed from the mailbox and put into a "save queue." The second messagein 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 expressionsExpressionsTimeoutand 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 canconnect 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入门:构建application练习3,实例演示如果构建一个最简单的Erlang Application
编写分布式的Erlang程序:陷阱和对策
Erlang入门:构建application练习5(监督树),以实例完全演示监督树的用法,Erlang入门必须知道的那点事
Erlang入门:构建application练习4(进程link的作用),实例演示进程link的作用及效果
《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF 《Erlang之父:为什么面向对象很糟糕》PDF
erlang文献及资料汇总 入门资料: erlang中文手册(R11B 文档译文,最适合入门) erlang位运算与二进制解析 erlang二进制高效编程 erlang异常处理详解 开发经验: 面对软件错误构建可靠的分布式系统 编写分布式的 ...
主要介绍了Erlang初学:Erlang的一些特点和个人理解总结,本文总结了函数式编程、一切都是常量、轻量进程、进程端口映射及典型缺点等内容,需要的朋友可以参考下
孟岩谈Erlang:并行计算和云计算,详细介绍了新一代编程语言Erlang在并行计算和云计算方面的特性
erlang最新 api
博文链接:https://maxtqm.iteye.com/blog/118429
confetti, Erlang配置提供程序/应用程序 纸屑五彩纸屑是你的Erlang应用程序的配置提供程序。基本上是 application:get_env/2 在类固醇上。特性管理控制台可以通过telnet维护部门访问将为你 love在运行时重新加载( ...
mecks_unit:一个简单的Elixir软件包,可以使用Erlang的:meck库优雅地模拟(异步)ExUnit测试中的模块功能
Introducing Erlang: Getting Started in Functional Programming by Simon St. Laurent English | 6 Mar. 2017 | ASIN: B06XHSP5SH | 212 Pages | AZW3 | 1.85 MB If you’re new to Erlang, its functional style...
MQTT客户端专为在机器对机器(M2M)和物联网(IoT)上下文中进行通信而设计,并实现了MQTT协议版本3.1和3.1.1。 该客户端是用Erlang编写的,并已通过Mosquitto和RabbitMQ等MQTT服务器进行了测试。
OpenEmbedded / Yocto Project层,用于Erlang和Elixir支持 此层提供对与和/或构建系统一起使用的和支持: 文献资料 请参阅。 依存关系 该层取决于: URI:git://git.openembedded.org/bitbake分支:主 URI:git:...
MQTT服务器设计用于在机器对机器(M2M)和物联网(IoT)上下文中进行通信,并实现了MQTT协议版本3.1和3.1.1。 服务器使用Erlang作为OTP应用程序编写。
Erlang是一种通用的面向并发的编程语言,它有瑞典电信设备制造商爱立信所辖的CS-Lab开发, 目的是创造一种可以应对大规模并发活动的编程语言和运行环境。
讲出Erlang网络协议并模拟网络上的Erlang节点。 完全能够与Erlang进行双向通信。 在合理范围内,Erlang类型已映射到Haskell类型。 发给Erlang的消息只是Haskell中的函数调用,而来自Erlang的消息则传递到MVars。 ...
Erlang特性: ● 并发性 - Erlang支持超大量级的并发进程,并且不需要操作系统具有并发机制。 ● 分布式 - 一个分布式Erlang系统是多个Erlang节点组成的网络(通常每个处理器被作为一个节点) ● 健壮性 - Erlang...
这个模拟程序会模拟Telecommunication system的生死过程,即是erlang B表的变体。注意这不是Erlang B公式变体