-module(dp). -export([start/1, stop/0]). fork() -> receive {pickup, Whom} -> Whom ! {a_fork, self()}, receive {putdown, Whom} -> fork() end end. room(Occupants, Capacity) -> receive {knock, Whom} when Occupants < Capacity -> Whom ! {enter, self()}, room(Occupants + 1, Capacity); {leave, _} -> room(Occupants - 1, Capacity) end. philosopher(Name, Room, LFork, RFork) -> think(Name), Room ! {knock, self()}, receive {enter, Room} -> ok end, LFork ! {pickup, self()}, RFork ! {pickup, self()}, pickup_forks(), eat(Name), LFork ! {putdown, self()}, RFork ! {putdown, self()}, Room ! {leave, self()}, philosopher(Name, Room, LFork, RFork). pickup_forks() -> receive {a_fork, Fork} -> receive {a_fork, _} -> ok after 100 -> Fork ! {putdown, self()}, pause(100), Fork ! {pickup, self()}, pickup_forks() end end. start(N) -> Control = spawn(fun () -> Room = spawn_link(fun () -> room(0, N - 1) end), Fork = spawn_link(fun fork/0), setup(N, Room, Fork, Fork) end), register(dining_philosophers, Control), ok. setup(N, Room, Left, Last) when N > 1 -> Right = spawn_link(fun fork/0), spawn_link(fun () -> philosopher(N, Room, Left, Right) end), setup(N - 1, Room, Right, Last); setup(1, Room, Left, Right) -> spawn_link(fun () -> philosopher(1, Room, Left, Right) end), receive _ -> exit({done}) end. stop() -> dining_philosophers ! stop, unregister(dining_philosophers), ok. pause(Milliseconds) -> receive after Milliseconds -> ok end. say(Name, Pred) -> io:format("Philosopher ~w ~s~n", [Name, Pred]). eat(Name) -> say(Name, "is eating."), pause(3000). think(Name) -> say(Name, "is thinking."), pause(500). ================================ -module(samefringe). -export([start/2,gen/2,gen/3]). say(String) -> io:format("~s ~n", [String]). gen([],top) -> receive { done } -> say("match"); _ -> say("no match") end; gen([],internal) -> true; gen([H|T],Level) when integer(H) -> receive { H1, P } -> if (H == H1) -> P ! { ok }, gen(T,Level); true -> P ! { stop }, say("no match") end; { done } -> say("no match") end; gen([H|T],Level) when list(H) -> gen(H,internal),gen(T,Level). gen([],P,top) -> P ! { done }; gen([],_,internal) -> true; gen([H|T],P,Level) when integer(H) -> P ! { H, self() }, receive { ok } -> gen(T,P, Level); { stop } -> say("no match") end; gen([H|T],P,Level) when list(H) -> gen(H,P,internal),gen(T,P,Level). start(T1,T2) -> say("starting samefringe ...."), Pid = spawn(samefringe,gen,[T1,top]), spawn(samefringe,gen,[T2,Pid,top]).