在Erlang餐饮哲学家 [英] Dining Philosophers in Erlang

查看:93
本文介绍了在Erlang餐饮哲学家的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你以前见过餐饮哲学家,那么你知道有几种方法可以做到。我的实现创建了与消息传递进行通信的哲学和叉子过程。

If you have ever seen Dining Philosophers before, then you know that there are a few ways to do it. My implementation creates philosopher and fork processes which communicate with message passing.

我在叉子和哲学家流程中有很多程序,但我自己想出来,现在我将分享完成的代码。我是初学者有一个美好的一天。

I was having a lot of program with format on the fork and philosopher processes, but I figured it out myself and now I will share the finished code. I'm a beginner fyi. Have a nice day.

-module(df).
-export([start/0, fork/2, philosopher/5]).

start() ->
SpawnForks = spawnForks([1,2,3,4], []),
SpawnForks2 = lists:reverse(SpawnForks),
main(SpawnForks2, [], 1).


%Creates a list of spawned fork processes
spawnForks([], ForkList) -> ForkList;
spawnForks([Head|Tail], ForkList) ->
  Fork = spawn(df,fork,[Head, "down"]),
spawnForks(Tail, [Fork|ForkList]).


%Philosopher 4 will have a different fork order
main(ForkList, PhilList, Count) when Count =:= 4 ->
  Fork1 = lists:nth(Count, ForkList),
  Fork2 = lists:nth(1, ForkList),
  %arguments to the philosopher: (Count = PhilosopherNumber, 2 = number of times to eat, fork1, fork2, self
  Philosopher = spawn(df, philosopher, [Count, 2, Fork1, Fork2, self()]),
  await([Philosopher|PhilList], ForkList);

  %philosophers 1-3 will have standard fork order.
main(ForkList, PhilList, Count) ->  
  Fork1 = lists:nth(Count, ForkList),
  Fork2 = lists:nth(Count + 1, ForkList),
  %arguments to the philosopher: (Count = PhilosopherNumber, 2 = number of times to eat, fork1, fork2, self
  Philosopher = spawn(df, philosopher, [Count, 2, Fork2, Fork1, self()]),
  Count2 = Count + 1,
main(ForkList, [Philosopher|PhilList], Count2).


%await waits for philosophers to be done and shuts down the fork processes
await([],[])-> ok;
await([],[Head|Tail]) -> 
    Head ! {shutdown}, await([], Tail);
await([Pid|Rest], ForkList)->
    receive {done, Pid} ->
    await(Rest, ForkList)
end.



%a fork process
%when state == down, accept pickup messages. After receiving a pickup request, 
%send an authorization. Print "fork up", and set fork State to up.
fork(Fork,State) when State =:= "down" ->
receive 
    {shutdown} -> exit(normal);
    {pickup, Pid, Philosopher} -> 
    io:format("Philosopher ~p picks up Fork ~p.\n",[Philosopher,Fork]),
    Pid ! {getfork, self()},
fork(Fork,"up")
    end;
%when state == up, accept putdown messages. After receiving a putdown request, 
%send an authorization. Print "fork up" and set fork State to up.
fork(Fork,State) when State =:= "up" ->
    receive
    {shutdown} -> exit(normal);
    {putdown, Pid, Philosopher} ->
    Pid ! {takefork, self()},
    io:format("Philosopher ~p puts down Fork ~p.\n",[Philosopher,Fork]),
fork(Fork,"down")
end.



%a philosopher process 
philosopher(_, Times, _,_, Main) when Times =:= 0 -> Main ! {done, self()}, exit(normal);
philosopher(Philosopher, Times, Fork1, Fork2, Main)->  
    io:format("Philosopher ~p is thinking.\n",[Philosopher]),
%request fork pickups on adjacent forks. wait for authorization messages and print "eating" 
    Fork1 ! {pickup, self(), Philosopher},
    receive 
    {getfork, Fork1} ->
                Fork2 ! {pickup, self(), Philosopher}
    end,
    receive         
    {getfork, Fork2} -> 
                io:format("Philosopher ~p is eating.\n",[Philosopher]),
                Fork1 ! {putdown, self(), Philosopher},
                Fork2 ! {putdown, self(), Philosopher},
                receive
                {takefork, Fork1} -> ok;
                {takefork, Fork2} -> ok
    end,
                Times2 = Times - 1,
philosopher(Philosopher, Times2, Fork1, Fork2, Main)
    end.


推荐答案

对于蝙蝠,我注意到两件事: / p>

Right off the bat, I noticed two things:


  1. 您有多个未终止的接收块 - 即,不结束匹配。请参阅Erlang / OTP文档此处

  2. here 。
  1. You have multiple unterminated receive blocks -- i.e., no end to match. See Erlang/OTP docs here.
  2. You likely have illegal guards. Instead of string:equal, you probably want to see if simple term comparison will work for you. See Erlang/OTP docs here.

最后,我知道很容易复制&粘贴到一个Stackoverflow问题,而不是打扰格式化,但是如果您的编辑器屏幕看起来像上面的代码,您可能希望为首选编辑器安装Erlang语言支持。缩进可以是你的朋友。 : - )

Finally, I know it's easy to copy & paste into a Stackoverflow question and not bother with formatting, but on the chance that your editor screen looks anything like that code above, you probably want to install the Erlang language support for your preferred editor. Indentation can be your friend. :-)

这篇关于在Erlang餐饮哲学家的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆