Sistemas Distribu´ıdos
Aula 3: Comunica¸
c˜
ao, Falhas e Coordena¸
c˜
ao
Comunica¸c˜
ao entre Processos
troca de mensagens ´
e sempre a primitiva b´
asica
sobre essa primiitiva podemos construir outras vis˜
oes da
comunica¸
c˜
ao
Mensagens B´
asicas
send (destino, &mensagem)
receive (origem, &mensagem)
quest˜
oes
semˆ
antica de opera¸c˜
oes
especifica¸
c˜
ao de origem e destino
formato da mensagem
semˆ
antica — envio s´ıncrono e ass´ıncrono
envio ass´ıncrono: execu¸
c˜
ao procede imediatamente
bufferiza¸
c˜
ao
envio s´ıncrono: execu¸
c˜
ao procede quando destinat´
ario recebe
mensagem
determinismo
recebimento s´ıncrono e ass´ıncrono
recebimento s´ıncrono ´
e o convencional
execu¸
c˜
ao procede quando h´
a algo a tratar
alternativa de recebimento com timeout
bloqueio!
suspens˜
ao da linha de execu¸
c˜
ao corrente at´
e chegada da
mensagem
bloqueio e recebimento expl´ıcito
espera por mensagens de tipos espec´ıficos?
podem haver outros tipos de mensagens pendentes
espera por qualquer tipo de mensagem
c´
odigo se torna um enorme emaranhado
recebimento ass´ıncrono
orienta¸c˜
ao a eventos: chegada de mensagem ´
e encarada como
evento a ser tratado
recebimento fica impl´ıcito
o recebimento impl´ıcito ´
e considerado um recebimento sem
bloqueio
outras formas de recebimento sem bloqueio ser˜
ao discutidas
Envio no TinyOS
interface AMSend {
command error_t send(am_addr_t addr, message_t* msg,
uint8_t len);
command error_t cancel(message_t* msg);
event void sendDone(message_t* msg, error_t error);
command uint8_t maxPayloadLength();
command void* getPayload(message_t* msg, uint8_t len);
}
preserva¸
c˜
ao de buffer ´
e responsabilidade do programador!
conceito de ownership
Recebimento no TinyOS
interface Receive {
event message_t* receive(message_t* msg,
void* payload, uint8_t len);
}
retorna (novo) buffer para camada de comunica¸
c˜
ao (buffer
swap)
possibilidades:
retorna msg sem mexer (por ex, “n˜
ao ´
e para mim!”)
copia dados para outro local e retorna
armazena msg em vari´
aveis locais e retorna endere¸
co de outro
message t*
exemplo (prox. lab): Recebimento
...
event void AMControl.startDone(error_t err) { if (err != SUCCESS) {
call AMControl.start(); }
}
event message_t* Receive.receive (message_t* msg, void* payload, uint8_t len) { if (len == sizeof(Msg)) {
Msg* localpkt = (Msg*)payload; if (post setLeds() == SUCCESS) {
data = localpkt->data; } } return msg; } Sistemas Distribu´ıdos
Manipula¸c˜
ao de Mensagens
acesso a campos de buffer apenas atrav´
es de interfaces:
interface Packet {
command void clear(message_t* msg);
command uint8_t payloadLength(message_t* msg);
command void setPayLoadLength(message_t* msg, uint8_t len); command uint8_t maxPayloadLength();
command void* getPayload(message_t* msg, uint8_t len); }
Modelo de Concorrˆ
encia
o que faz com que programa TinyOS se torne ass´ıncrono
72 Execution model H/WTimer TimerMilliC Application RandomLfsrP command,event task interrupt handler task execution(sync) interrupt execution(async)
Figure 5.1 TinyOS execution model: both tasks (full lines) and interrupt handlers (dotted lines) cross component boundaries.
5.2
Tasks
A task is a simple deferred computation mechanism provided by nesC. Tasks have a
return value of void, take no parameters (this keeps the task scheduler very simple) and
are declared with the task keyword:
task void s e t u p T a s k () { // task code }
Using the post keyword schedules a task for later execution:
event void Boot . booted () {call Timer . s t a r t P e r i o d i c (1024); post s e t u p T a s k ();
}
In the above example, once TinyOS completes the boot sequence (signals Boot.
booted to all components), it will run setupTask.
Tasks are like any other module code. They can access variables, call commands,
signal events, and invoke internal or global C functions. The post operator is like calling
a function: it has a return value of error_t. Posting a task always returns SUCCESS
unless the task is already pending. Put another way, a component cannot post multiple
copies of the same task to run; however, once a task has started executing it may
repost itself.
This is the core TinyOS scheduler loop that runs after the system boots. This
function never returns. It executes tasks until the task queue is empty, then puts the
microcontroller to sleep:
Variantes s´ıncronas e ass´ıncronas
algumas bibliotecas oferecem primitivas com v´
arias diferentes
Especifica¸c˜
ao de destino
endere¸camento direto (acoplamento)
endere¸
cos e volatilidade
servi¸
cos de nomes
caixas de correios e canais (desacoplamento)
endere¸
cos bem conhecidos
comunica¸
c˜
ao com par “qualquer”
Formato de mensagens
no n´ıvel mais baixo: sequˆ
encias de bytes
interpreta¸
c˜
ao por conta do programa
valores com tipos
canais ou mailboxes com tipo declarado
chamadas remotas
Falhas parciais
A no¸
c˜
ao de “falha parcial” ´
e fundamental nos SDs: a coopera¸
c˜
ao
entre processos deve ser tolerante a falhas individuais
Sistemas Distribu´ıdosFalhas – Nomenclatura
problemas inevit´
aveis: falhas (faults)
m´
aquinas quebradas, desconex˜
oes, erros no software
erros (failures): consequˆ
encias dessas falhas
nomenclaturas variam mas temos que manter consistente a id´
eia
Falhas – Nomenclatura
omiss˜
ao
temporiza¸c˜
ao
falhas arbitr´
arias ou bizantinas
Dependabilidade
termo cl´
assico “tolerˆ
ancia a falhas” por vezes considerado
enganador
dependabilidade: id´
eia de que se pode confiar no sistema
(apesar de poss´ıveis erros)
dependabilidade
reliability
availability
safety
security
Processos e enlaces
Usaremos duas abstra¸
c˜
oes principais para representar o sistema
f´ısico: processos e enlaces
Processos: abstraem entidades ativas e executam
processamento (pode representar um computador, um
processador, uma thread, etc.)
Enlace: abstraem a rede de comunica¸
c˜
ao f´ısica l´
ogica que
permite a troca de mensagens entre processos
Coordena¸c˜
ao
processos em aplica¸
c˜
ao distribu´ıda devem se coordenar para
Coordena¸c˜
ao e Padr˜
oes
utiliza¸c˜
ao de padr˜
oes recorrentes de intera¸c˜
ao
muitos problemas recaem em vers˜
oes diversas do problema de
acordo distribu´ıdo: ex., processos concordam sobre a ordem de
tratamento de mensagens, se um evento ocorreu ou n˜
ao, etc.
...assunto espec´ıfico do curso de algoritmos distribu´ıdos
Coordena¸c˜
ao: acordo sobre hora
hora certa ´
e conceito extremamente ´
util para sincronizar
atividades no “mundo real”
em sistemas computacionais:
ordena¸
c˜
ao
depura¸
c˜
ao
escalonamento de atividades
medidas
...
Rel´
ogios f´ısicos
cada m´
aquina tipicamente tem um rel´
ogio f´ısico
circuito que gera interrup¸
c˜
oes a cada n oscila¸
c˜
oes
rel´
ogios f´ısicos exibem uma taxa de varia¸c˜
ao em rela¸
c˜
ao a
hora real
tempo
hora
relógio
hora certa
drift máximo
Sistemas Distribu´ıdosSincroniza¸c˜
ao de rel´
ogios f´ısicos
interna
diferen¸ca m´
axima entre horas de dois rel´
ogios do sistema
externa
diferen¸
ca m´
axima entre horas de qualquer rel´
ogio do sistema e
uma fonte externa
Algoritmos de sincroniza¸c˜
ao de rel´
ogio
trocas de mensagens repetidas para obten¸c˜
ao de diversas
amostras
protocolo NTP atualmente o mais difundido
hora = T
hora corrente?
p
q
Representa¸c˜
ao de algoritmos distribu´ıdos
Modelo de computa¸
c˜
ao reativa
Adotaremos um modelo de computa¸
c˜
ao reativa onde componentes
do mesmo processo se comunicam trocando eventos: modelo de
composi¸
c˜
ao baseado em eventos ass´ıncronos
Um algoritmo ser´
a descrito como um conjunto de tratadores de
Aplica¸c˜
oes como cole¸c˜
oes de componentes
Cada processo cont´
emm
um conjunto de m´
odulos
de software, chamados
componentes
Cada componente ´
e
identificado por um nome,
provˆ
e uma interface na
forma de eventos que ele
aceita ou produz e possui
um conjunto de
propriedades
Combina¸c˜
ao de componentes para construir pilhas de
software
Internamente, cada
componente ´
e constru´ıdo
como uma m´
aquina de
estados cujas transi¸
c˜
oes
s˜
ao disparadas por
eventos
Eventos podem
“carregar” informa¸
c˜
ao,
como dados lidos ou IDs
de processos
Intera¸c˜
ao entre pilhas de software
Eventos – nota¸c˜
ao
Eventos ser˜
ao denotados por < EventType|att1, att2, ...| >
Eventos do mesmo componente s˜
ao processados na ordem em
que foram disparados (ordem FIFO)
Cada tratador de evento ´
e processado at´
e o fim antes do
pr´
oximo tratador ser iniciado
Mensagens trocadas entre processos distintos podem precisar ser
ordenadas de acordo com algum crit´
erio usando mecanismos
Exemplo de c´
odigo nos componentes
upon event <Event1 | att1, att2, ...> do
...faz algo...
trigger <Event2 | att1, att2, ...>;//
envia evento
upon event <Event3 | att1, att2, ...> do
...faz algo...
trigger <Event4 | att1, att2, ...>; //envia evento
Desacoplamento e intera¸c˜
ao ass´ıncrona
as mensagens recebidas de outros processos s˜
ao transformadas
em eventos
desacoplamento entre origem e destino
novos processos podem se “juntar” ou “deixar” o sistema
distribu´ıdo em qualquer momento
um processo deve estar pronto para tratar a altera¸
c˜
ao de
participantes
A ordem de execu¸
c˜
ao dos eventos n˜
ao pode ser definida a priori:
Interface de programa¸c˜
ao
request: usado por um
componente para
requisitar um servi¸
co de
outro componente
confirmation: usado por
um componente para
confirmar a conclus˜
ao de
uma requisi¸
c˜
ao
indication: usado por um
componente para entregar
(deliver) informa¸
c˜
oes para
outro componente
Exemplo de m´
odulo de impress˜
ao
M´
odulo
Module:
Name: Print
Events:
Request: <PrintRequest | rqid, str>
Confirmation: <PrintConfirm | rqid>
Algoritmo
Implements:
upon event <PrintRequest | rqid, str> do
print(str);
Exemplo de servi¸co de impress˜
ao com n
o
de requisi¸c˜
oes
limitado
M´
odulo
Module:
Name: BoundedPrint
Events:
Request: <BoundedPrintRequest | rqid, str>
Confirmation:<PrintStatus | rqid,status>: Ok/Nok
Indication: <PrintAlarm>: indica o limite
Exemplo... impress˜
ao com n
o
de requisi¸c˜
oes limitado
Algoritmo
Implements: BoundedPrint
Uses: Print
upon event <Init> do
bound := Threshold;
upon event <BoundedPrintRequest | rqid, str> do
if bound > 0 then
bound := bound - 1;
trigger <PrintRequest | rqid, str>;
if bound = 0 then trigger <PrintAlarm>;
else
trigger <PrintStatus | rqid, Nok>;
upon event <PrintConfirm | rqid> do
Inicializa¸c˜
ao
Init
evento gerado automaticamente pelo sistema de execu¸
c˜
ao
quando um componente ´
e criado
pode ser usado para inicializar o componente
Bibliografia
1
Introduction to Reliable Distributed Programming, R.
Guerraoui and L. Rodrigues, Springer, 2006
2