We apologize if the code is difficult to execute. This is the classic problem of philosophers in the dining room, where 5 philosophers eat, but there are only 5 chopsticks - and you need to eat.
These are instructions if anyone is interested: http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf
Anyway, here is the code, the chopstick 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.
Philosopher 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, Right, Left, Name, Ctrl). **%This was wrong, it should say start(Hungry, Right, Left, Name, Ctrl) -> spawn_link(fun() -> dream(Hungry, Right, Left, Name, Ctrl) end).** dream(Hungry, Right, Left, Name, Ctrl) -> Time = 500+uniform:random(500), **%This was wrong, it should say random:uniform** timer:sleep(Time), Right! {request, self()}, Left! {request, self()}, %skicka {request, self()} till tvĂĽ pinnar wait(Hungry, Right, Left, Name, Ctrl). wait(Hungry, Right, Left, Name, Ctrl) -> receive granted -> io:format("~s received a chopstick~n", [Name]), receive granted -> io:format("~s received a chopstick~n", [Name]), io:format("~s started eating~n", [Name]), eat(Hungry, Right, Left, Name, Ctrl) end; _ -> wait(Hungry, Right, Left, Name, Ctrl) end. eat(Hungry, Right, Left, Name, Ctrl) -> Time = 500+uniform:random(500), **%This was wrong, it should say random:uniform** timer:sleep(Time), Right! returned, Left! returned, io:format("~s put back two chopsticks~n", [Name]), if Hungry =< 1 -> Ctrl ! done; true -> dream(Hungry-1, Right, Left, Name, Ctrl) end.
And finally, the host 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, C2, C3, "Avicenna", Ctrl), eater:start(5, C3, C4, "Plato", Ctrl), eater:start(5, C4, C5, "Kant", Ctrl), eater:start(5, C5, C1, "Descartes", Ctrl), wait(5, [C1, C2, C3, C4, 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.
Conclusion:
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 even read all this, I have not yet learned to read erlang error reports. If you can and want to tell me what this means, please do it.