I have been reading ‘Erlang Programming‘ , like a good student, I decided to solve the ring exercise:
Here is the problem in my words:
Create a linked list of N Ring where each Ring is an erlang process. When you pass a message to the head Ring , it should propagate the message to the next Ring and that propagates to the next ring and so on. I added additional clause — “Each ring should report its successful message delivery to the previous ring and the previous ring should print successful message delivery from its child rings.
Here is the code:
-module(ring).
-compile(export_all).
createRing(N) ->
Self = self(),
Head = spawn(fun() -> ring(N, Self) end),
Head.
ring(N, PreviousRing) when N > 0 ->
Self = self(),
io:format('~w #ring created PID: [~w] ListenerPid: [~w] ~n',[N, Self, PreviousRing]),
NextRing = spawn(fun() ->
ring(N-1 , Self) end),
loop(N ,NextRing, PreviousRing);
ring(N, PreviousRing) ->
io:format('last ring reached! ~w ~n',[N]),
NullRing = spawn(fun() ->
receive
Any ->
io:format('dummy ring received ~w ~n', Any)
end
end),
loop(N, NullRing, PreviousRing).
loop(N, NextRing, PreviousRing) ->
receive
{send_message, Message} ->
io:format('ring # ~w with pid: #~w received ~w ~n',[N, self(), Message]),
NextRing ! {send_message, Message},
PreviousRing ! {ok, self()},
loop(N, NextRing, PreviousRing);
{ok, NextRing} ->
io:format('~w with pid# ~w successfully sent message ~n',[N-1, NextRing]),
loop(N, NextRing, PreviousRing);
{quit} ->
io:format('quiting ring: ~w with Pid: ~w ~n',[N, self()])
end.
sendMessage(Head, M) when M > 0 ->
Head ! {send_message, M},
sendMessage(Head, M - 1);
sendMessage(Head, M) ->
io:format('sending last message ~n'),
Head ! {send_message, M}.
I have had my share of multi-threaded programming in Java, thanks to the telephony applications I’v worked on. Just imagine the pain you would have to go through to implement this in Java / C++ !
nice article