如果您以前看过《哲学家就餐》,那么您就会知道有几种方法可以做到这一点。我的实现创建了与消息传递进行通信的哲学家和分叉进程。
我有很多关于分叉和哲学家进程格式的程序,但我自己弄清楚了,现在我将分享完成的代码。我是初学者仅供参考。祝你今天过得愉快。
-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.