[erlang-questions] Question regarding problems in Joe's book
David Stokar
david.stokar@REDACTED
Fri Aug 10 17:11:45 CEST 2007
Agreeing to Toby (
http://www.erlang.org/pipermail/erlang-questions/2007-July/028133.html) I
got the following:
-module(conc_problems).
-export([start/2,start_server/0]).
%% 2> c(conc_problems).
%% {ok,conc_problems}
%% 3> conc_problems:start_server(). This starts the registration
server (A singleton)
%% true
%% 4> conc_problems:start(foo2, fun area_server1:loop/0). This calls the
registration method on the above singleton server
%% Received:{foo2,#Fun<area_server1.loop.0>}
%% Undef:foo2
%% {foo2,#Fun<area_server1.loop.0>,{success,<0.46.0>}}
%% 5> conc_problems:start(foo2, fun area_server1:loop/0).
%% Received:{foo2,#Fun<area_server1.loop.0>}
%% Def: <0.46.0>:{foo2,#Fun<area_server1.loop.0>}
%% {foo2,#Fun<area_server1.loop.0>,{fail,<0.46.0>}}
%% 6> foo2 ! {self(),{circle, 9}}.
%% {<0.31.0>,{circle,9}}Server: Area of circle is 254.469
%% start/2
%% start(AnAtom, Fun) to register AnAtom as spawn(Fun).
%% Make sure your program works correctly in the case when two
%% parallel processes simultaneously evaluate start/2. In this case,
%% you must guarantee that one of these processes succeeds and the
%% other fails.
start(AnAtom,Fun) ->
rpc(starter, {AnAtom,Fun}).
%% start_server()
%% Starts the server loop and registers
%% the process as starter
start_server() ->
register(starter,spawn(fun() -> loop([]) end)).
%% rpc(Pid, Request)
%% Forwards Request to Server Pid
%% Makes process wait for Response from Server
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
{Pid, Response} ->
Response
after 3000 ->
io:format("Rpc timed out")
end.
%% start_fun
%% Starts fun Fun and registers
%% it as AnAtom if undefined
%% Returns:
%% {success, PID} if undefined
%% {fail, PID} if allready registered
start_fun(undefined,{AnAtom,Fun}) ->
io:format("Undef:~p~n" ,[AnAtom]),
PID = spawn(Fun),
register(AnAtom,PID),
{success,PID};
start_fun(PID,X) ->
io:format("Def: ~p:~p~n", [PID,X]),
{fail,PID}.
%% loop(x)
%% Processes messages send to the server
%% Prints the message out
loop(X) ->
receive
{Pid, {AnAtom, Fun}} ->
io:format("Received:~p~n" ,[{AnAtom, Fun}]),
REG = whereis(AnAtom),
Status = start_fun(REG, {AnAtom,Fun}),
%% self() has to be replaced by starter
%% because self() == starter evaluates to false
%% rpc waits for {starter, Response}
Pid ! {starter,{AnAtom, Fun, Status}},
loop(X)
end.
The circle: (Without timer)
-module(conc_problems_ring).
-compile(export_all).
%% start_ring(N,M, Mesg)
%% N number of processes in Ring
%% M number of roundings
%% Mesg the message to transport
start_ring(N,M,Mesg) ->
[Head|Pids] = [ start() || _ <- lists:seq(1,N)],
Head ! {self(), {Pids, [], M}, Mesg}.
%% start()
%% Starts the server loop
start() -> spawn(fun() -> loop([]) end).
%% rpc(Pid, Request)
%% Forwards Request to Server Pid
%% Makes process wait for Response from Server
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
{Pid, Response} ->
Response
end.
%% loop(x)
%% Processes messages send to the server
%% Prints the message out
loop(X) ->
receive
{_, {Pids,VisitedPids,Rounds}, Message} ->
io:format("~nReceived: ~p Pid: ~p Round: ~p~n" ,[Message,
self(), Rounds]),
{TagNP, {NPs, NVPs, NRounds}} = next_pid(Pids, VisitedPids,
Rounds),
case {TagNP, NRounds} of
{last,_} ->
io:format(" finished last~n"),
true;
{NP,0} ->
io:format(" finished~n"),
NP ! {self(), {NPs, NVPs, NRounds}, Message},
true;
{NP,_} ->
io:format(" pass on~n"),
NP ! {self(), {NPs, NVPs, NRounds}, Message},
loop(X)
end
end.
%% next_pid(NextPids, PassedPids, Rounds)
%% Returns the next Pid out of the NextPids list
%% If NextPids is empty, we finished a round
%% and decrease the value of Rounds.
%% We can then restart by taking PassedPids as next Pids
next_pid([],_,0) -> {last,{[],[],[]}};
next_pid([],[NP|R],M) -> {NP,{R,[self()],M-1}};
next_pid([NP|R],X,M) -> {NP,{R,[self()|X],M}}.
Session:
1> c(conc_problems_ring).
{ok,conc_problems_ring}
2> conc_problems_ring:start_ring(3,2,"Hi").
{<0.31.0>,{[<0.39.0>,<0.40.0>],[],2},"Hi"}
Received: "Hi" Pid: < 0.38.0> Round: 2
pass on
Received: "Hi" Pid: <0.39.0> Round: 2
pass on
Received: "Hi" Pid: <0.40.0> Round: 2
pass on
Received: "Hi" Pid: < 0.39.0> Round: 1
pass on
Received: "Hi" Pid: <0.38.0> Round: 1
finished
Received: "Hi" Pid: <0.39.0> Round: 0
finished
Received: "Hi" Pid: < 0.40.0> Round: 0
finished last
3>
Enjoy David Stokar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070810/65ab917c/attachment.htm>
More information about the erlang-questions
mailing list