Upload
giuliana-dias
View
215
Download
2
Embed Size (px)
Citation preview
Programação Concorrente em Programação Concorrente em ErlangErlang
Grupo:Grupo:Alexandre SiebraAlexandre SiebraByron BezerraByron BezerraIgor SampaioIgor Sampaio
Mozart Araújo FilhoMozart Araújo FilhoSérgio QueirozSérgio Queiroz
2Por que Erlang?Por que Erlang?
• Necessidade de uma linguagem simbólica de alto nível visando alcançar uma maior produtividade
• Inexistência de uma linguagem que tivesse todas as características necessárias ao desenvolvimento de sistemas de telecomunicações– Concorrência implícita na linguagem– Tratamento de erros
3CaracterísticasCaracterísticas• Tempo real• Suporte a projetos de
larga escala• Sistemas non-stop• Portabilidade• Concorrência• Incremental code
loading
• Comunicação entre processos– assíncrona– unidirecional
• Distribuição• Garbage collection • Robustez• Timing
4SintaxeSintaxe
-module(math1).-export([area/1]).area({square, Side}) -> Side * Side;area({rectangle, X, Y}) -> X * Y;area({triangle, A, B, C}) -> S = (A + B + C)/2, math:sqrt(S*(S-A)*(S-B)*(S-C)).
5SintaxeSintaxe
• Como chamar?> Thing = {triangle, 6, 7, 8}.{triangle,6,7,8}> math1:area(Thing).20.3332
6ConcorrênciaConcorrência
• Sintaxe das primitivas
– spawn: Cria um novo processo concorrente para avaliar a Função e retorna o seu identificador (Pid).
Pid = spawn (Módulo, Função, ListArg)
– ! (send): Envia uma mensagem para um processo.Pid ! Message
7ConcorrênciaConcorrência– receive: Recebe uma mensagem de um
processo.receive Message1 [when Guard1] -> Actions1; Message2 [when Guard2] -> Actions2; ...end
8Ordem de Recebimento de Ordem de Recebimento de
MensagensMensagens• As mensagens enviadas a um dado processo
são armazenadas em uma “caixa-postal”.
Head
msg_1
msg_2
msg_3
msg_4
(a)
receive msg_3 -> ...end
msg_1
msg_2
msg_4
(b)
receive msg_4 -> ... msg_2 -> ...end
Head
msg_1
msg_4
(c)
msg_4
(d)
receive AnyMessage -> ...end
Head Head
9TimeoutsTimeouts
• Argumento opcional da primitiva receive• Caso nenhuma mensagem tenha sido processada
em t milisegundos, realiza uma açãoget_event() ->
receive {mouse, click} -> receive {mouse, click} -> double_click after double_click_interval() -> single_click end ... end.
10Processos RegistradosProcessos Registrados
• Primitivas Básicas– register(Nome, Pid)
• Associa o Nome ao processo Pid.– unregister(Nome)
• Remove a associação entre Nome e um processo.– whereis(Nome)
• Retorna o identificador de processo associado com Nome. Se nenhum processo estiver associado com Nome, retorna undefined.
– registered()• Retorna uma lista de todos os nomes registrados.
11Modelo Cliente-ServidorModelo Cliente-Servidor
Solicitação
Clientes
Servidor
O próximo exemplo é um servidor que pode ser usado em uma central telefônica para analisar os
números discados pelos usuários.
12ExemploExemplo-module(number_analyser).-export([start/0,server/1]).-export([add_number/2,analyse/1]).Start() -> register(number_analyser,
spawn(number_analyser, server, [nil])).
%%Funções de Interface.add_number(Seq, Dest) -> request({add_number,Seq,Dest}).analyse(Seq) -> request({analyse,Seq}).request(Req) -> number_analyser ! {self(), Req}, receive {number_analyser,Reply} -> Reply end.
13Exemplo (continuação)Exemplo (continuação)%%Servidor.
Server(AnalTable) ->
receive {From, {analyse,Seq}} -> Result = lookup(Seq,AnalTable), From ! {number_analyser, Result}, server(AnalTable); {From, {add_number, Seq, Dest}} -> From ! {number_analyser, ack}, server(insert(Seq, Dest, AnalTable))
end.
- Enviando a mensagem ao servidor:number_analyser ! {self(), {analyse,[1,2,3,4]}}
14Terminação de ProcessosTerminação de Processos
• Terminação Normal– Fim da função pela qual foi chamado– Chamada a exit(normal)
• Terminação Anormal– Chamada a exit(Reason)onde Reason é
qualquer termo válido, com exceção de normal
– Falha em tempo de execução (ex.: divisão por zero)
15Terminação de ProcessosTerminação de Processos
• Processos Ligados (“linked”)– Bidirecional (A B B A)– Quando um processo termina, um sinal EXIT é
enviado para todos os processos ligados a ele{‘EXIT’, Exiting_Pid, Reason}
– Reason•normal Ignore• Caso contrário, termine anormalmente e envie
‘EXIT’ a todos os processos ligados– Primitivas
•link(Pid), unlink(Pid)
16ExemploExemplo
Sinal Exit
Sinal Exit
17Programação DistribuídaProgramação Distribuída
MotivaçãoMotivação– Velocidade: devido à distribuição da aplicação a
diferentes nós* do sistema;– Confiabilidade e tolerância a falhas: falhas isoladas
não afetam o comportamento do sistema como um todo;
– Acesso a recursos de outros nós;– Extensibilidade: pode-se melhorar a performance
adicionando novos nós.* Nó: sistema Erlang completo e independente. Em uma rede distribuída,
um ou mais nós podem ser executados em um único computador.
18Mecanismos DistribuídosMecanismos Distribuídos
• Primitivas Básicas– spawn (Node, Mod, Func, Args)
• Cria um processo em um nó remoto.– spawn_link (Node, Mod, Func, Args)
• Além de criar um processo, gera um link para o mesmo.– {Name, Node} ! Msg
• Envia Msg ao processo nomeado Name dentro do Node.– monitor_node (Node, Flag)
• Caso Flag seja true, faz com que o processo que chamou essa função monitore se Node está “vivo”. Caso contrário, pára de monitorar.
19Mecanismos DistribuídosMecanismos Distribuídos
• Primitivas Básicas– node()
• Retorna próprio nome do nó.– nodes ()
• Retorna uma lista dos nomes de outros nós conhecidos.– node (Item)
• Retorna o nome do nó de origem de Item.– disconnect_node (Nodename)
• Desconecta o nó referido do nó Nodename.
20Exemplo do BancoExemplo do Banco
21Código do ServidorCódigo do Servidor-module(bank_server).-export([start/0, server/1]).start() -> register(bank_server, spawn(bank_server, server, [[]])).server(Data) -> receive {From, {deposit, Who, Amount}} -> From ! {bank_server, ok}, server(deposit(Who, Amount, Data)); {From, {ask, Who}} -> From ! {bank_server, lookup(Who, Data)}, server(Data);
22Código do Servidor (cont.)Código do Servidor (cont.) {From, {withdraw, Who, Amount}} -> case lookup(Who, Data) of undefined -> From ! {bank_server, no}, server(Data); Balance when Balance > Amount -> From ! {bank_server, ok}, server(deposit(Who, -Amount, Data)); _ -> From ! {bank_server, no}, server(Data) end end.
23Código do ClienteCódigo do Clientelookup(Who, [{Who, Value}|_]) -> Value;lookup(Who, [_|T]) -> lookup(Who, T);lookup(_,_) -> undefined.
deposit(Who, X, [{Who, Balance}|T]) -> [{Who, Balance+X}|T];deposit(Who, X, [H|T]) -> [H|deposit(Who, X, T)];deposit(Who, X, []) -> [{Who, X}].
24Código do Cliente (cont.)Código do Cliente (cont.)-module(bank_client).-export([ask/1, deposit/2, withdraw/2]).
head_office() -> ‘[email protected]’.
ask(Who) -> call_bank({ask, Who}).
deposit(Who, Amount) -> call_bank({deposit, Who, Amount}).
withdraw(Who, Amount) -> call_bank({withdraw, Who, Amount}).
25Código do Cliente (cont.)Código do Cliente (cont.)call_bank(Msg) -> Headoffice = head_office(), monitor_node(Headoffice, true), {bank_server, Headoffice} ! {self(), Msg), receive {bank_server, Reply} -> monitor_node(Headoffice, false), Reply; {nodedown, Headoffice} -> no end.
26Links de ReferênciaLinks de Referência
• Erlang Systems Homepage– http://www.erlang.se
• Open Source Erlang– http://www.erlang.org