很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。如需帮助澄清这个问题以便重新打开它,visit the help center .
9年前关闭。
如果代码难以遵循,我深表歉意。
这是经典的哲学家就餐问题,有 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, 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.
最后是宿主进程:
-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.
输出:
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 的错误报告。如果可以,并且想告诉我这意味着什么,请这样做。
最佳答案
我认为问题在于你有三个模块:dinner
, eater
, 和 chopstick
,但尝试调用philospher:start
在您的 dinner:init/0
功能。试试 eater:start
反而。
第二个问题是生成随机数时模块和函数名的顺序;替换 uniform:random
与 random:uniform
在您的 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, Right, Left, Name, Ctrl) ->
spawn_link(fun() -> dream(Hungry, Right, Left, Name, 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
...
谢谢。这很有趣。
关于concurrency - Erlang - 餐饮哲学家的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8073878/