Exercício 10

OC 1999/2000 (Exercícios Práticos)


Enunciado

Desenvolva um módulo em Erlang que modelize uma estrutura master-slave em que o master garanta que os slaves se mantêm "vivos":

As funções a desenvolver são:

Instruções recomendadas:


Solução

-module(exercicio10).

-export([start/1, slave/0, to_slave/2]).

-define(MASTER, andy@pcigb10).

start( N ) ->
    register( master, self() ),
    process_flag(trap_exit, true ),
    Lista_slaves = cria_slaves( N, [] ),
    process_msgs( Lista_slaves ).


slave( ) ->
    receive
        die ->
            true;
        Msg ->
            io:format("Mensagem recebida: ~w~n", [Msg]),
            slave()
    end.

process_msgs( Lista_slaves ) ->
    receive
        { to_slave, Num_slave, Msg } ->
            send_msg( Lista_slaves, Num_slave, Msg ),
            process_msgs( Lista_slaves );

        { 'EXIT', Pid, Razao } ->
            case recria_slave( Lista_slaves, Pid ) of
                erro ->
                    io:format("Erro desconhecido~n", []),
                    process_msgs( Lista_slaves );

                Lista_slaves_nova ->
                    io:format("processo ~w terminou por ~w, e foi recriado~n",[element(1, hd(Lista_slaves_nova)), Razao] ),
                    process_msgs( Lista_slaves_nova )
            end
    end.

cria_slaves( 0, L ) -> L;
cria_slaves( N, L ) ->
    cria_slaves( N-1, [ { N, spawn_link(?MODULE, slave, []) } | L ] ).

recria_slave( Lista_slaves, Pid_slave ) ->
    case [X || X <- Lista_slaves, element(2, X) == Pid_slave ] of
        [ { Num_slave, Pid_slave } ] ->
            NovoSlave = { Num_slave, spawn_link(?MODULE, slave, []) },
            [ NovoSlave | [X || X <- Lista_slaves, element(2, X) =/= Pid_slave ] ];
        _ ->
            erro
    end.

send_msg( Lista_slaves, Num_slave, Msg ) ->
    case [ X || X <- Lista_slaves, element(1, X) == Num_slave ] of
        [ {Num_slave, Pid_slave} ] ->
            Pid_slave ! Msg;
        _ ->
            erro
    end.

to_slave( Msg, N ) ->
    { master, ?MASTER } ! { to_slave, N, Msg }.


Última actualização: 17-05-2000

OC 1999/2000 (Exercícios Práticos)