-module(ring).
-export([start/3, manager/0, loop/1]).
start(M, N, Message) ->
register(manager, spawn(ring, manager, [])),
io:format("Manager is ~w~n", [manager]),
manager!{create, N},
manager!{send, M, Message},
manager!{stop},
ok.
manager() ->
%This process manages ring processes
receive
{create, N} ->
PList = create(N, []), %Create the processes list
[First|_] = PList, %Pickup the first one
setup(First, PList), %Setup the ring
register (ring, First), %Identify the ring by the first Process
manager();
{send, M, Message} -> %When receiving messages
send(ring, M, Message), %send them to the ring
manager();
{stop} -> %When receiving stop
ring!{stop, self()} %stop the ring
end.
create(0, PList) -> PList;
create(N, PList) ->
create(N-1, [spawn(ring, loop, [[]])|PList]).
setup(First, [Head|[]]) ->
Head!{setNext, First}; %Link the last process to the first
setup(First, [Head|PList]) ->
[Next|_] = PList,
Head!{setNext, Next},
setup(First, PList).
send(_, 0, _) -> ok;
send(First, M, Message) ->
First!{message, self(), Message},
send(First, M-1, Message).
loop(Next) ->
receive
{setNext, NextPid} ->
io:format("~w linked to ~w~n",[self(), NextPid]),
loop([NextPid|Next]);
{message, Pid, Message} ->
io:format("~w received message from ~w: ~w~n", [self(), Pid,
Message]),
[NextPid|_] = Next,
NextPid!{message, self(), Message},
loop(Next);
{stop, Pid} ->
io:format("~w received stop message from ~w~n", [self(), Pid]),
[NextPid|_] = Next,
NextPid!{stop, self()}
end.
it needs some tweaking so feel free to send any comment.
Regards.
Sami Bouafif.
Below a solution where a central process sets up the ring and manage
it.
-module(ring).
-export([start/3, manager/0, loop/1]).
start(M, N, Message) ->
It need some tweaking, so feel free to send any critic.
Regards,
Sami.