process - erlang function call out of order? -
i modified kitchen module learn erlang using standard io functions see gets printed out in order of execution , found strange. ran next in shell
3> pid = spawn(kitchen, fridge2, [[baking_soda]]). <0.41.0> 4> kitchen:store(pid, water). 0 2 1 ok ok
it seems me function store has phone call function fridge2 before receive clause in store function right after 0 printed out , after 2 printed receive clause executed , 1 printed. modified code below. how fridge2 function called store function? because of parallel execution somehow? line {pid, msg} ->
in store function? function call? , why ok printed?
-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}} -> ! {self(), ok}, fridge1(); {from, {take, _food}} -> %% uh.... ! {self(), not_found}, fridge1(); terminate -> ok end. fridge2(foodlist) -> receive {from, {store, food}} -> ! {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]), ! {self(), {ok, food}}, fridge2(lists:delete(food, foodlist)); false -> io:format("~p~n", [4]), ! {self(), not_found}, fridge2(foodlist) end; terminate -> ok end.
similar case statements, receive uses pattern matching determine clause execute. {pid, msg}
clause match 2-tuple.
let's walk through execution of code --
pid = spawn(kitchen, fridge2, [[baking_soda]]).
this spawns new process executes kitchen:fridge2/1
function. function blocks until receives message either 2-tuple of form {from, {[store|take], food}}
or atom 'terminate'.
kitchen:store(pid, water).
meanwhile, phone call above function shell. sends message {self(), {store, food}}
new process, prints "0" , waits receive message 2-tuple.
the other process has received message satisties receive. sends message {self(), ok}
process sent message, prints "2", recursively calls , 1 time again waits receive message.
the shell process has received message , continues execution. prints "1" , prints sec element of tuple received ("ok"). returns 'ok' shell.
the shell prints result ("ok") , displays prompt.
the sec process still waiting receive message.
process erlang
No comments:
Post a Comment