[erlang-questions] Newbie question can't explain behaviour of my program (tutorial exercise masterslave)

David Budworth <>
Tue Jun 23 14:36:06 CEST 2009


Have you tried from the regular "erl" or "werl" shell?  the output you
pasted is from erlide, which maybe is not showing all the erlang output
until some buffer limit is reached? (never used erlide, so no idea)

but your code is correct, I just tried it, and here was my shell's output
(note, all 5 procs started instantly):
1> c(masterslave).
./masterslave.erl:101: Warning: variable 'Reason' is unused
{ok,masterslave}
2> masterslave:start(5).
Slave: 5 with Pid: <0.44.0> created
true
Slave: 4 with Pid: <0.45.0> created
Slave: 3 with Pid: <0.46.0> created
Slave: 2 with Pid: <0.48.0> created
Slave: 1 with Pid: <0.49.0> created
3> masterslave:to_slave(hello,2).
Slave 2 recieved the message: hello
{message_to_slave,{hello,2}}
4> masterslave:to_slave(die,1).
Slave 1 with old PID <0.49.0> restarted with new Pid:
<0.51.0>
{message_to_slave,{die,1}}
5> masterslave:stop().
Master going downstop
6>

On Mon, Jun 22, 2009 at 7:29 AM, Folkert Hendrix <>wrote:

> Hi,
>
> I did the tutorial exercise Master Slave
> (http://erlang.org/course/exercises.html#ms ) and it does work, but i
> can't explain it's behaviour. Is my code wrong?:
> this is the output i get:
> ()6> masterslave:start(5).
> Slave: 5 with Pid: <0.97.0> created
> true
> Slave: 4 with Pid: <0.98.0> created
> Slave: 3 with Pid: <0.99.0> created
> ()7> masterslave:to_slave(hello,2).
> Slave: 2 with Pid: <0.101.0> created
> Slave: 1 with Pid: <0.106.0> created
> Slave 2 recieved the message: hello
> {message_to_slave,{hello,2}}
> ()8> masterslave:to_slave(die,1).
> {message_to_slave,{die,1}}
> Slave 1 with old PID <0.106.0> restarted with new Pid: <0.108.0>
> ()9> masterslave:stop().
> Master going downstop
> ()10>
>
> Questions:
>
> In the process view of toolbar:start(). I only see 4 slaves created.
> When i give the command masterslave:to_slave(hello,2) then the rest of
> the slaves are created and can i see the registered master. Slave 2
> responds but it wasn't created yet?
> When the master stop, the slaves also stop, but i expected the slave
> received the exit signal and should write a message.
>
> the code:
> %% Author: fh
> %% Created: Jun 19, 2009
> %% Description: TODO: Add description to masterslave
> -module(masterslave).
>
> %%
> %% Include files
> %%
> -include_lib("eunit/include/eunit.hrl").
> %%
> %% Exported Functions
> %%
> -export([start/1, stop/0, to_slave/2, init/1, loop_master/1,
> loop_slave/0]).
>
> %%
> %% API Functions
> %%
>
> %% Start the master and tell it to start N slave processes.
> %% Register the master as the registered process master.
> start(N) ->
>    register(master, spawn(?MODULE, init, [N]) ).
>
>
>
> %%The slave should print all messages it recieves except the message die
> loop_slave() ->
>    receive
>        {master, {say, {Msg, N}}} ->
>            io:format("Slave ~w recieved the message: ~w~n",[N, Msg]),
>            loop_slave();
>        {master, die} ->
>            exit("Slave Died");
>        {'EXIT', master, _Reason} ->
>            io:format("Slave exit normal"),
>            exit(normal)
>    end.
>
> %%
> %% Interface functions
> %%
>
>
> %% Send a message to the master and tell it to relay the message to slave
> N.
> %% The slave should exit (and be restarted by the master) if the message is
> die.
> to_slave(Message, N) ->
>    master ! {message_to_slave, {Message, N}}.
>
> stop() ->
>    master ! stop.
>
>
>
> %%
> %% Local Functions
> %%
>
> init(N) ->
>    process_flag(trap_exit, true),
>    init_slave(N, []).
>
>
> init_slave(0, Slaves) ->
>    loop_master(Slaves);
>
> init_slave(N, Slaves) ->
>    Pid = spawn_link(?MODULE, loop_slave, []),
>    io:format("Slave: ~w with Pid: ~w created~n",[N, Pid]),
>    init_slave(N-1,[{N,Pid} | Slaves]).
>
> restart_slave(Pid, Slaves) ->
>    {N, OldPid } = lists:keyfind(Pid,2,Slaves),
>    NewPid = spawn_link(?MODULE, loop_slave, []),
>    io:format("Slave ~w with old PID ~w restarted with new Pid:
> ~w~n",[N, OldPid, NewPid]),
>    lists:keyreplace(Pid, 2, Slaves, {N, NewPid}).
>
>
> %% return slave N
> master_to_slave(Slaves, N, Msg) ->
>        case lists:keyfind(N,1,Slaves) of
>            false -> io:format("Slave ~w doesn't excist!",[N]);
>            {_N, Pid} -> Pid ! {master, Msg}
>        end.
>
>
> %% handle messages from slaves
> %% The master should detect the fact that a slave processe died,
> %% restart it and print a message that it has done so.
> loop_master(Slaves) ->
>    receive
>        {message_to_slave, {Message, N}} when Message == die ->
>            master_to_slave(Slaves,N, die),
>            loop_master(Slaves);
>        {message_to_slave, {Message, N}} ->
>            master_to_slave(Slaves,N, {say, {Message, N}}),
>            loop_master(Slaves);
>        stop ->
>            io:format("Master going down"),
>            exit("Master stopped");
>        {'EXIT', Pid, Reason} ->
>            NewSlaves= restart_slave(Pid, Slaves),
>            loop_master(NewSlaves);
>        Other ->
>             error_logger:error_msg( "Error: Process ~w got unknown
> msg ~w~n.", [self(), Other]),
>            loop_master(Slaves)
>    end.
>
>
> Regards,
> Folkert
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


More information about the erlang-questions mailing list