如果代码很难遵循,我道歉.
这是经典的餐饮哲学家问题,有5位哲学家正在吃饭,但只有5支 – 你需要两只才能吃.
这是经典的餐饮哲学家问题,有5位哲学家正在吃饭,但只有5支 – 你需要两只才能吃.
如果有人有兴趣,这些是说明:
http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf
-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.
哲学家流程代码:
-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.
最后是主持人流程:
-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.
输出:
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}]}
非常感谢,如果你读完所有这些,我还没有学会如何阅读erlang的错误报告.如果可以,并想告诉我这意味着什么,请做.
解决方法
我认为问题在于你有三个模块:晚餐,吃饭和筷子,但是试着打电话给philospher:从晚餐开始:init / 0功能.尝试吃饭:改为开始.
第二个问题是生成随机数时模块和函数名称的顺序;替换制服:随机随机:你的eater.erl制服:
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 ...
这很快就显示了第三个问题 – 我们应该从第一个错误报告中发现 – 食者实际上并不在他们自己的过程中.所以编辑eater.erl以便start()函数读取:
start(Hungry,Ctrl) -> spawn_link(fun() -> dream(Hungry,Ctrl) end).
现在它按预期工作:
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 ...
谢谢.这很有趣.