Critique of solution to an exercise from the online course
pete-erlang-questions@REDACTED
pete-erlang-questions@REDACTED
Thu Aug 4 00:15:12 CEST 2005
[Disclaimer: I have no experience with functional programming, but
I've been intrigued recently about Erlang (the poker server blog and
the comparison of yaws to apache). I decided to investigate and
printed some of the documentation which I read on vacation last week
sitting by a pool. In other words, please be gentle.]
I'm trying to learn Erlang and I'm doing some of the sample exercises
from the online course (linked in the documentation section of the
erlang.org site), but I was hoping someone might provide some feedback
on my solution to one of the problems.
Here is the question:
2) Write a function which starts N processes in a ring, and sends a
message M times around all the processes in the ring. After the
messages have been sent the processes should terminate gracefully.
And here is my solution:
-module(ring).
-export([start/2, start/4, head/1, head/2, node/2]).
start(NumProcesses, NumTokenPasses) ->
HeadOfRing = spawn(ring, head, [NumTokenPasses]),
start(NumProcesses - 1, NumTokenPasses, HeadOfRing, HeadOfRing).
start(0, _NumTokenPasses, NextNode, HeadOfRing) ->
%% After all of the processes have been spawned, send the head of
%% the ring a message so that it can get a reference to its next
%% node which was not known when it was spawned.
HeadOfRing ! {next_node, NextNode};
start(NumProcesses, NumTokenPasses, NextNode, HeadOfRing) ->
Pid = spawn(ring, node, [NumTokenPasses, NextNode]),
start(NumProcesses - 1, NumTokenPasses, Pid, HeadOfRing).
head(NumTokenPasses) ->
receive
{next_node, NextNode} ->
%%io:format("~p HeadOfRing received START token~n", [self()]),
head(NumTokenPasses, NextNode)
end.
head(0, _NextNode) ->
%%io:format("~p HeadOfRing is exiting~n", [self()]),
{done, head, self()};
head(NumTokenPasses, NextNode) ->
%%io:format("~p HeadOfRing sending token~n", [self()]),
NextNode ! token,
receive
token ->
%%io:format("~p HeadOfRing received token~n", [self()]),
head(NumTokenPasses - 1, NextNode)
end.
node(0, _NextNode) ->
%%io:format("~p Node is exiting~n", [self()]),
{done, self()};
node(NumTokenPasses, NextNode) ->
receive
token ->
%%io:format("~p Node received token~n", [self()]),
%%io:format("~p Node sending token~n", [self()]),
NextNode ! token,
node(NumTokenPasses - 1, NextNode)
end.
Aside from comments and suggestions, I'd also appreciate any ideas why
my processes aren't exiting correctly. Things work for a while but
then things fall apart on me.
kaz@REDACTED:~/work/src/erlang$ erl
Erlang (BEAM) emulator version 5.4.6 [source] [threads:0]
Eshell V5.4.6 (abort with ^G)
1> ring:start(1000, 100).
{next_node,<0.1031.0>}
2> length(processes()).
24
3> ring:start(1000, 10000).
{next_node,<0.2033.0>}
4> length(processes()).
1024
5>
Thanks for the help.
Pete
More information about the erlang-questions
mailing list