Correcção do teste

Exame - 26 de Junho de 2000

OC98-99 (testes)


Condições gerais da prova

Índice


Questões

1. Desenvolva em linguagem Erlang, um conjunto de funções que modelize o sistema distribuído representado no seguinte diagrama operacional:

Resposta:

-module(pergunta_1).
-export([start/0, inicio/0, p_d/1, p_e/1, p_f/1, p_r/0]).
start() ->
	spawn(?MODULE,inicio,[]).
inicio() ->
	P_r=spawn(?MODULE,p_r,[]),
	P_f=spawn(?MODULE,p_f,[P_r]),
	P_d=spawn(?MODULE,p_d,[P_f]),
	P_e=spawn(?MODULE,p_e,[P_r]),
	loop(P_r,P_f,P_d,P_e).
loop(P_r,P_f,P_d,P_e) ->
	receive
		{A,B,C} -> ok
	end,
	P_d ! {A,C},
	P_e ! {A,B},
	loop(P_r,P_f,P_d,P_e).
p_r() ->
	receive
		{E,B} -> ok
	end,
	receive
		{F} -> ok
	end,
	io:format("Resultado: ~w.~n",[F+E-B]).
p_f(P_r) ->
	receive
		{D,A} -> P_r ! {D/A},
	end,
	p_f(P_r).
p_d(P_f) ->
	receive
		{A,C} -> P_f ! {A*A-C,A},
	end,
	p_d(P_F).
p_e(P_r) ->
	receive
		{A,B} -> P_r ! {2*A,B},
	end,
	p_e(P_r).
Índice

2. Desenvolva em linguagem Erlang, um sistema tolerante a falhas centralizado, representado no diagrama seguinte.

Resposta:

-module(pergunta_2).
-export([master/1, slave/0]).
master(N_slaves) ->
	process_flag(trap_exit,true),
	L_slaves=cria_slaves(N_slaves),
	loop(L_slaves).
cria_slaves(N) ->
	cria_slaves(N,[]).
cria_slaves(0,L_slaves) ->
	L_slaves;
cria_slaves(N,L_slaves) ->
	P=spawn_link(?MODULE,slave,[]),
	cria_slaves(N-1,[P|L_slaves]).
loop(L_slaves) ->
	receive
		{'EXIT',Pid,normal} ->
			L_slaves_nova=retira_da_lista(Pid,L_slaves),
			loop(L_slaves_nova);
		{'EXIT',Pid,_Reason} ->
			L_slaves_inter=retira_da_lista(Pid,L_slaves),
			L_salves_nova=cria_slaves(1,L_slaves_inter),
			loop(L_slaves_nova)
	end.
retira_da_lista(Pid,L_slaves) ->
	[X || X<-L_slaves,X=/=Pid].

Índice  

3. Considere um sistema bancário, em que diversos bancos são responsáveis pelas transacções entre contas:

a) Represente por meio de diagrama, o processo de transacção financeira descrita.
b) Complete o código seguinte, referente ao ciclo do servidor.

Resposta:

a)

b)

-module(pergunta_3).
-export([start/2, banco/2]).
start(Nome_banco,Contas) ->
	spawn(?MODULE, banco,[Nome_banco,Contas]).
banco(Nome_banco,Contas) ->
	register(Nome_banco,self()),
	loop(Nome_banco,Contas).
loop(Nome_banco,Contas) ->
	receive
		{transaccao_1,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia} ->
			Contas_novas=processa_pedido(Conta_A,{Banco_B,Conta_B},Quantia,Contas),
			loop(Nome_banco,Contas_nova);
		{transaccao_2,{Banco_A,Conta_A},{Nome_banco,Conta_B},Quantia} ->
			Contas_novas=processa_confirmacao({Banco_A,Conta_A},Conta_B,Quantia,Contas),
			loop(Nome_banco,Contas_nova)
	end.
processa_confirmacao({Banco_A,Conta_A},Conta_B,Quantia,Contas) ->
	Pid_B=quem_titular_B(Conta_B),
	PIN_B=pin_titular_B(Conta_B),
	Pid_B ! {transaccao_2_1,{Banco_A,Conta_A},Conta_B,Quantia},
	receive
		{transaccao_2_2,{Banco_A,Conta_A},Conta_B,Quantia,PIN_B} ->
			aceita_transaccao({Banco_A,Conta_A},Conta_B,Quantia,Contas);
		{transaccao_2_2,{{Banco_A,Conta_A},Conta_B,_Quantia,_PIN_B} ->
			recusa_transaccao({Banco_A,Conta_A},Conta_B,Quantia),
			Contas
	end.
processa_pedido(Conta_A,{Banco_B,Conta_B},Quantia,Contas) ->
	case quem_titular_A(Conta_A) of
		erro ->
			Contas;
		Pid_A ->
			Nome_banco=get_name(self()),
			Banco_B ! {transaccao_2,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia},
			receive
				{transaccao_3,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia,ok} ->
					Pid_A ! {transaccao_4,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia,ok},
					actualiza_quantia(Conta_A,-Quantia,Contas);
				{transaccao_3,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia,recusada} ->
					Pid_A ! {transaccao_4,{Nome_banco,Conta_A},{Banco_B,Conta_B},Quantia,recusada},
					Contas
			end
	end.
aceita_transaccao({Banco_A,Conta_A},Conta_B,Quantia,Contas) ->
	Nome_banco=get_name(self()),
	Banco_A ! {transaccao_3,{Banco_A,Conta_A},{Nome_banco,Conta_B},Quantia,ok},
	actualiza_quantia(Conta_A,Quantia,Contas).
recusa_transaccao({Banco_A,Conta_A},Conta_B,Quantia) ->
	Nome_banco=get_name(self()),
	Banco_A ! {transaccao_3,{Banco_A,Conta_A},{Nome_banco,Conta_B},Quantia,recusada}.

Índice


Última actualização: 19-07-2000

OC98-99 (testes)