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:
-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