Critique of solution to an exercise from the online course

Gunilla Arendt <>
Fri Aug 5 08:24:57 CEST 2005


Hi Pete!

The code looks fine to me! My only comment is that only start/2 (to be 
called from the shell) and head/1 and node/2 (used in spawn/3 calls) 
need to be exported, the other functions IMO are internal.

If you would like to practice some more, you could consider that 
actually all processes in the ring have an almost identical behavior. 
That is, you don't have to distinguish between the head process and the 
rest of the processes, which means even less code is needed. (Hint: let 
each process start the next process in the ring.)

Good luck!

/ Gunilla

 wrote:
> [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.
> 
> :~/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
> 
> 


-- 
_____Gunilla Arendt______________________________________________
OTP Development
  +46-8-7275730  ecn 851 5730



More information about the erlang-questions mailing list