Learn you some Erlang using standard IO functionsの kitchen モジュールを変更して、何が実行順に出力されるかを確認したところ、非常に奇妙なことがわかりました。基本的に、シェルで次を実行しました
3> Pid = spawn(kitchen, fridge2, [[baking_soda]]).
<0.41.0>
4> kitchen:store(Pid, water).
0
2
1
ok
ok
0 が出力された直後に store 関数の receive 句の前に関数 store が関数 fridge2 を呼び出し、次に 2 が出力された後に receive 句が実行され、最終的に 1 が出力されるようです。変更後のコードは以下です。ストア関数から冷蔵庫2関数を呼び出す方法は? これはどういうわけか並列実行のためですか?この行は{Pid, Msg} ->
store 関数で何をしますか? 関数呼び出しですか?そして、なぜokが印刷されるのですか?
-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.