It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center




已关闭8年。




如果代码难以理解,我深表歉意。
这是经典的用餐哲学家问题,有5位哲学家在吃饭,但只有5条棍棒-您需要吃2根。

这些是说明,如果有人感兴趣的话:
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的错误报告。如果可以,并想告诉我这意味着什么,请执行。

最佳答案

我认为问题在于您有三个模块:dinnereaterchopstick,但是尝试在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/

10-10 19:42