加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

并发 – Erlang – Dining Philosophers错误

发布时间:2020-12-14 05:47:19 所属栏目:Java 来源:网络整理
导读:如果代码很难遵循,我道歉. 这是经典的餐饮哲学家问题,有5位哲学家正在吃饭,但只有5支 – 你需要两只才能吃. 如果有人有兴趣,这些是说明: http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf 无论如何,这里
如果代码很难遵循,我道歉.
这是经典的餐饮哲学家问题,有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
...

谢谢.这很有趣.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读