Concurrency – Erlang – dining philosophers error
If the code is hard to follow, I apologize
If anyone is interested, these are instructions: http://www.kth.se/polopoly_fs/1.260940 !/ Menu/general/column-content/attachment/philosophers. pdf
In any case, here is the code, chopsticks process code:
-module(chopstick).
-export([start/0]).
start() ->
spawn_link(fun() -> init() end).
init() ->
available().
available() ->
receive
{request,From} ->
From ! granted,gone();
quit ->
ok
end.
gone() ->
receive
returned ->
available();
quit ->
ok
end.
Process code:
-module(eater).
-import(timer,[sleep/1]).
-import(random,[uniform/1]).
-export([start/5,dream/5,eat/5,wait/5]).
start(Hungry,Right,Left,Name,Ctrl) ->
dream(Hungry,Ctrl).
**%This was wrong,it should say start(Hungry,Ctrl) ->
spawn_link(fun() -> dream(Hungry,Ctrl) end).**
dream(Hungry,Ctrl) ->
Time = 500+uniform:random(500),**%This was wrong,it should say random:uniform**
timer:sleep(Time),Right! {request,self()},Left! {request,%skicka {request,self()} till två pinnar
wait(Hungry,Ctrl).
wait(Hungry,Ctrl) ->
receive
granted ->
io:format("~s received a chopstick~n",[Name]),receive
granted ->
io:format("~s received a chopstick~n",io:format("~s started eating~n",eat(Hungry,Ctrl)
end;
_ -> wait(Hungry,Ctrl)
end.
eat(Hungry,Ctrl) ->
Time = 500+uniform:random(500),Right! returned,Left! returned,io:format("~s put back two chopsticks~n",if
Hungry =< 1 ->
Ctrl ! done;
true ->
dream(Hungry-1,Ctrl)
end.
Finally, the moderator process:
-module(dinner).
-export([start/0]).
start() ->
spawn(fun() -> init() end).
init() ->
C1 = chopstick:start(),C2 = chopstick:start(),C3 = chopstick:start(),C4 = chopstick:start(),C5 = chopstick:start(),Ctrl = self(),eater:start(5,C1,C2,"Confucios",Ctrl),**% This is where it crashes**
eater:start(5,C3,"Avicenna",C4,"Plato",C5,"Kant","Descartes",wait(5,[C1,C5]).
wait(0,Chopsticks) ->
lists:foreach(fun(C) -> C ! quit end,Chopsticks);
wait(N,Chopsticks) ->
receive
done ->
wait(N-1,Chopsticks);
abort ->
erlang:exit(abort)
end.
Output:
11> dinner:start().
<0.85.0>
12>
=ERROR REPORT==== 10-Nov-2011::02:19:10 ===
Error in process <0.85.0> with exit value: {undef,[{uniform,random,[500]},{eater,dream,5},{dinner,init,0}]}
Thank you very much. If you've read all this, I haven't learned how to read Erlang's error reports yet If you can and want to tell me what this means, please do it
Solution
I think the problem is that you have three modules: dinner, dinner and chopsticks, but try calling philospher: start with dinner: init / 0 function Try eating: start instead
The second problem is the order of module and function names when generating random numbers; Replace uniform: random: your eater ERL uniform:
1> dinner:start(). <0.35.0> Confucios received a chopstick Confucios received a chopstick Confucios started eating Confucios put back two chopsticks Confucios received a chopstick Confucios received a chopstick Confucios started eating Confucios put back two chopsticks Confucios received a chopstick Confucios received a chopstick Confucios started eating Confucios put back two chopsticks Confucios received a chopstick Confucios received a chopstick Confucios started eating Confucios put back two chopsticks Confucios received a chopstick Confucios received a chopstick Confucios started eating Confucios put back two chopsticks Avicenna received a chopstick Avicenna received a chopstick Avicenna started eating ...
This quickly shows the third problem - we should find from the first error report - that the eaters are not actually in their own process So edit eater ERL for the start() function to read:
start(Hungry,Ctrl) ->
spawn_link(fun() -> dream(Hungry,Ctrl) end).
Now it works as expected:
1> dinner:start(). <0.35.0> Confucios received a chopstick Plato received a chopstick Confucios received a chopstick Confucios started eating Descartes received a chopstick Kant received a chopstick Confucios put back two chopsticks Avicenna received a chopstick ...
thank you. It's interesting
