关于receive的理解,总算理解到了,相关见erlang面试题中receive的理解。
下面给出三个例子
第一个例子来实现:
- 清空邮箱一个消息
- 清空邮箱一个指定消息
- 清空邮箱所有消息
来证明
- receive 只会遍历邮箱一次;下一次遍历,是在受到新消息的时候
- 遍历邮箱的时候,匹配到一个,立刻结束匹配的过程,不回继续进行
- 不加after语句的话,receive 遍历邮箱完毕,如果没有匹配到,就会阻塞在receive这里;如果匹配到了,就会执行receive end后面的代码块;
第二个例子是实现消息先后顺序接受的实现,即:
只能处理消息'a'后,才能开始处理消息'b';
如果消息'b'先到,那么不会处理
第三个例子是实现消息的优先级的接受,来自
《learn you some erlang for great good》
例子1:
%%%-------------------------------------------------------------------
%%% @author mohe
%%% @copyright (C) 2016, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 02. 九月 2016 下午3:07
%%%-------------------------------------------------------------------
-module(test).
-author("mohe").
%% API
-compile(export_all).
init() -> %%初始化
Pid = spawn(fun() -> loop() end),
register(test, Pid).
loop() -> %%主循环
io:format("loop in"),
receive
ok ->
io:format("receive ok,begin process"),
io:format("receive ok,begin end"),
loop();
'flush' ->
flush(),
loop();
{'flush', Msg} ->
flush(Msg),
loop();
'flush_all' ->
flush_all()
end.
flush() -> %%清除一个消息
receive
Msg ->
io:format("flush:~p", [Msg])
after 0 ->
ok
end.
flush(Msg) -> %%清除一个指定消息
receive
Msg ->
io:format("flush:~p", [Msg])
after 0 ->
ok
end.
flush_all() -> %%清除所有的消息
receive
Msg ->
io:format("flush:~p", [Msg]),
flush_all()
after 0 ->
ok
end.
运行过程
<pre>
test:init(). //初始化
test!ok1. //发送'ok1'消息
test!ok2. //发送'ok2'消息
test!ok3. //发送'ok3'消息
test!ok1. //发送'ok1'消息
erlang:process_info(whereis(test),messages). //查看邮箱结果,结果为:{messages,[ok1,ok2,ok3,ok1]}
//清空邮箱一个消息
test!flush.
erlang:process_info(whereis(test),messages). //查看邮箱结果,结果为:{messages,[ok2,ok3,ok1]},
证明邮箱消息顺序是按序到达的
// 清空邮箱指定消息
test!ok1. //发送'ok1'消息
erlang:process_info(whereis(test),messages).
{messages,[ok2,ok3,ok1,ok1]}
test!{flush,'ok1'}.
erlang:process_info(whereis(test),messages).
{messages,[ok2,ok3,ok1]
说明只会遇到匹配成功后,立刻停止匹配过程,
因为匹配前有两个'ok1',匹配后,还剩下一个'ok1'
</pre>
例子2
receive
'a' ->
io:format("receive and process msg:~")
receive
'b' ->
io:format("receive and process msg:~")
end
end.
例子3
-module(multiproc).
important() ->
receive
{Priority, Message} when Priority > 10 ->
[Message | important()]
after 0 ->
normal()
end.
normal() ->
receive
{_, Message} ->
[Message | normal()]
after 0 ->
[]
end.