erlang函数调用乱序?
Posted
技术标签:
【中文标题】erlang函数调用乱序?【英文标题】:erlang function call out of order? 【发布时间】:2013-02-01 15:06:13 【问题描述】:我使用标准 IO 函数从 Learn you some Erlang 修改了厨房模块,以查看按执行顺序打印的内容,我发现了一些非常奇怪的东西。基本上我在shell中运行了以下内容
3> Pid = spawn(kitchen, fridge2, [[baking_soda]]).
<0.41.0>
4> kitchen:store(Pid, water).
0
2
1
ok
ok
在我看来,函数 store 在打印出 0 之后的 store 函数中的 receive 子句之前调用了函数 freezer2,然后在打印了 2 之后,执行了接收子句并最终打印了 1。修改后的代码如下。如何从 store 函数中调用冰箱函数?这是因为以某种方式并行执行吗?这行 Pid, Msg ->
在 store 函数中是做什么的?是函数调用吗?为什么可以打印?
-module(kitchen).
-compile(export_all).
start(FoodList) ->
spawn(?MODULE, fridge2, [FoodList]).
store(Pid, Food) ->
Pid ! self(), store, Food,
io:format("~p~n", [0]),
receive
Pid, Msg ->
io:format("~p~n", [1]),
io:format("~p~n", [Msg]),
Msg
end.
take(Pid, Food) ->
Pid ! self(), take, Food,
receive
Pid, Msg -> Msg
end.
store2(Pid, Food) ->
Pid ! self(), store, Food,
receive
Pid, Msg -> Msg
after 3000 ->
timeout
end.
take2(Pid, Food) ->
Pid ! self(), take, Food,
receive
Pid, Msg -> Msg
after 3000 ->
timeout
end.
fridge1() ->
receive
From, store, _Food ->
From ! self(), ok,
fridge1();
From, take, _Food ->
%% uh....
From ! self(), not_found,
fridge1();
terminate ->
ok
end.
fridge2(FoodList) ->
receive
From, store, Food ->
From ! self(), ok,
io:format("~p~n", [2]),
fridge2([Food|FoodList]);
From, take, Food ->
case lists:member(Food, FoodList) of
true ->
io:format("~p~n", [3]),
From ! self(), ok, Food,
fridge2(lists:delete(Food, FoodList));
false ->
io:format("~p~n", [4]),
From ! self(), not_found,
fridge2(FoodList)
end;
terminate ->
ok
end.
【问题讨论】:
【参考方案1】:类似于 case 语句,receive 使用模式匹配来确定要执行的子句。 Pid, Msg
是一个匹配任何 2 元组的子句。
让我们来看看你的代码的执行 --
Pid = spawn(kitchen, fridge2, [[baking_soda]]).
这会产生一个执行kitchen:fridge2/1
函数的新进程。该函数会一直阻塞,直到它接收到一个 2 元组 From, [store|take], Food
或原子“终止”的消息。
kitchen:store(Pid, water).
同时,您从 shell 调用上述函数。它将消息self(), store, Food
发送到该新进程,打印“0”,然后等待接收二元组消息。
另一个进程现在收到了一条满足其接收要求的消息。它将消息self(), ok
发送回发送消息的进程,打印“2”,递归调用自身并再次等待接收消息。
shell 进程现在已收到一条消息并继续执行。它打印“1”,然后打印它收到的元组的第二个元素(“ok”)。最后它返回 'ok' 给 shell。
shell 打印结果(“ok”)并显示提示。
第二个进程仍在等待接收消息。
【讨论】:
感谢您的信息。发布此主题后,我开始对代码有了更多的了解,但是您更加支持了我的理解,谢谢!以上是关于erlang函数调用乱序?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 erlang spawn 函数调用中出现语法错误 - “之前的语法错误:')'”?