Title: Exclus
1Exclusão Mútua Distribuída
- Principais Referências
- Livro Chow, Johnson, Cap. 10
- Livro M.Raynal Distributed Algorithms and
Protocols, Cap. 2 - Livro Valmir Barbosa An Introduction to Distr.
Algorithms, Cap. 8 - Velazquez, M., A Survey of Distributed Mutual
Exclusion Algorithms, Technical Report CS-93-116,
Colorado State University, 1993
2Observações sobre Notação
- A maioria dos Algoritmos serão descritos em
pseudo-código, onde - a variável me (ou equivalente) contém o índice
do processo corrente e não pode ser alterada - as demais variáveis são globais no processo
- não há compartilhamento de variáveis entre
processos, mas estes podem ter várias threads que
compartilham as variáveis globais - cada thread será composta de clausulas
reativas da forma - when Evento Condição gt Ações
- Onde
- Evento pode ser de controle (START), chamada da
aplicação, chegada de mensagem (recvd), ou de
temporização (timer T1) - Condição sobre as variáveis que
habilita/desabilita esta clausula - Ações sequência de instruções executadas
atomicamente - assume-se que referências para os processos
pares ja são conhecidos (topologia de
interconexão pré-estabelecida) - assume-se a existência de procedimentos
auxiliares (operações sobre filas, pilhas, etc.)
3Exclusão Mútua Distribuída
- Usado para sincronizar/coordenar as ações de
processos distribuídos em um sistema de forma
descentralizada. - Exemplos
- garantir o acesso exclusivo a dados/arquivos
compartilhados - garantir a serialização de operações sobre o
ambiente externo (p.ex. Robôs cooperativos) - garantir a consistência de páginas em uma
Memória compartilhada distribuída (DSM) - Exclusão Mútua Distribuída
- consiste em garantir o acesso exclusivo de um
processo (dentre vários com requisições
concorrentes) a uma seção crítica (recurso/
dado/serviço compartilhado). - ? é caso específico de um Problema de Acordo
(Agreement) - A principal diferença com relação à Sistemas
centralizados (p.ex. sincronização em um
Sist.Operacional) - ? não há o compartilhamento de memória toda
sincronização precisa ser feita através do envio
de mensagens
4Exclusão Mútua Distribuída Definição do Problema
- Sejam N processos Pi, i 1,..,N que interagem
através de mensagens e devem sincronizar os seus
acessos a um recurso compartilhado (pode ser
trivialmente generalizado para gt1 recurso) - No código de cada Pi
- enter() // entrada na seção crítica
- acesso exclusivo ao recurso compartilhado
- exit() // saida da seção crítica
- Para este tipo de problema, é muito difícil lidar
com falhas de nós! - ? Todos processos precisam chegar a um acordo
sobre a ordem de acesso. - As Premissas mais comuns
- processos não falham
- comunicação é confiável e
- mensagens não são duplicadas ou corrompidas
- Não há premissas sobre temporização (? sistemas
assíncronos)
5Requisitos Essenciais e Opcionais
- Segurança (Safety) ltessencialgt
- No máximo, um processo executa a cada momento na
seção crítica - Vivacidade (Liveness) ltessencialgt
- Todo pedido de entrada e/ou saida da seção
crítica é eventualmente atendido - ? com isto, evita-se deadlock e starvation
- Atendimento em Ordem ltopcionalgt
- Os pedidos para entrar na seção crítica são
atendidos em conformidade com a ordem causal. - ? isto garante tratamento justo (Fairness)
6Exclusão Mútua Distribuída
- Existem três abordagens
- Algoritmos baseados em token
- Algorítmos baseados em timestamps
- Algoritmos baseados em votação
7Algoritmos baseados em um token
- Ideia geral
- uma mensagem especial (token) é passada entre os
processos - o processo que possuir o token é aquele com
direito de executar na seção crítica - ao deixar a seção crítica, o processo detentor
do token deve repassa-lo a um outro processo que
esteja esperando entrar na seção - Tradução dos principais requisitos essenciais
- deve existir um único token (Segurança)
- o token precisa ser capaz de chegar a qualquer
processo participando da sincronização
(Vivacidade) - Para isto, todos os algoritmos nesta abordagem
definem uma estrutura lógica de comunicação para
passagem do token. - As estruturas mais comuns
- anel
- arvore
8Algoritmo de Token Circulante
- Neste caso, a estrutura lógica é um anel
conectando todos os processos participantes da
sincronização. - O Modelo de sistema (Premissas)
- topologia de interconexão é fixa (anel), mas
de processos arbitrário - comunicação é confiável (token não é perdido)
- comunicação é segura (token não é duplicado nem
modificado) - processos não falham
- Cada processo que deseja entrar na seção crítica
- espera a chegada do token do antecessor (vizinho
à esq/dir), - durante a sessão crítica, mantém o token
- após sair da seção crítica passa o token para o
próximo processo (vizinho do qual não recebeu o
token) - Processos que não precisam entrar na SC, passam o
token adiante imediatamente - Nota-se que satisfeitas as premissas, este
algoritmo garante - segurança, vivacidade, mas não garante
atendimento em ordem - ? Algoritmo tem simetria textual, mas o envio do
token é um overhead independente da freqüência de
requisições para a SC
9Algoritmo do Token Circulante
- O controle do repasse do token é feito por um
processo, que recebe requisições enter_region e
exit_region da aplicação (naquele nó), e tokens
circulantes do processo predecessor prev no anel.
Estados waiting e ? waiting
Proc(i)
Bool waiting when recv(appl,enter_region) ?
waiting gt waiting true when recv(prev,token)
gt if (waiting) reply(appl,enter_regi
on) recv(appl,exit_region) waiting
false send(next,token)
10Algoritmo de Token Circulante
- Mas se houver a possibilidade de perda do token,
é necessário que os processos possam detectar
isto. - Idéia central do Algoritmo de Misra83
- além do token principal t1 (usado para controlar
o acesso à SC), usar um token circulante
complementar t2, de valor oposto a t1 (isto é, t2
- t1) - o token t2 circula no mesmo sentido que token t1
- a cada vez que os tokens se encontram em um
processo, seus valores são atualizados (p.ex.
t1 e t2-- ) - se um processo P receber qualquer um dos tokens
com o mesmo valor mais de uma vez ? isto
significa que o outro token se perdeu - o token perdido pode ser reconstruído a partir
do token complementar - o 1º processo capaz de fazer esta detecção é o
processo que deveria ter recebido o token perdido
(este será o responável por recriar o token
perdido)
Misra83 Misra, J. Detecting Termination of
Distributed Computations using Markers, 2nd ACM
Conf. On Principles of Distributed Computing,
August 83, pp.290-294.
11Algoritmo de Token Circulante
Seja mi uma variável em Pi que guarda o último
valor de um token (t1 ou t2) visto. Atributo
t.val armazena o contador associado ao
token when recv (i - 1, t1) if (mi t1.val)
// t2 foi perdido mi (t1.val) new(t
2) // recriando t2 t2.val - t1.val
send(i1, t2 else mi t1.val se não
desejar entrar na seção critica send(i1,
t1) when recv (i -1, t2) // análogo ao caso
anterior, trocando t2 por t1 e vice-versa when
encontro (t1, t2) t1.val t2.val--
12Premissas Problemas
- Modelo de sistema do algoritmo de Misra83
- sistema assíncrono
- canais de comunicação são seguros
- processos não falham
- canal de comunicação tem falhas de omissão
perdas de mensagem são esporádicas (não há
partição) e - não ocorrem falhas simultâneas em mais de um
canal (ou seja, no máximo um token é perdido) - Características
- Simetria textual do algoritmo
- Problemas
- Overhead além do token principal, t1, um
segundo token sempre circula - Para evitar falsa detecção de perda de token, os
valores absolutos assumidos por t1 e t2 precisam
ser diferentes de todos os valores mi, ? seus
incrementos precisam ser no mínimo mod N1 (pois
tokens podem se encontrar até N vezes) -
13Primeiro Trabalho
- Generalizar o algoritmo de Misra83 para k gt 2
perdas de mensagens simultâneas. - Dica usar k1 tokens circulantes (token T0
controla a entrada na sessão crítica) e não se
restringir a comparação direta entre os valores
opostos de tokens - O trabalho em 2 etapas
- Descrição do algoritmo, discussão sobre o modelo
de sistema (em papel) até 2/04 - Implementação avaliação através de simulações
(de perda de tokens) usando Neko até 30/04
14Generalização de Misra83
Idéia Central Tokens se controlam 2-a-2 T0
ltgtT1 T1ltgtT2,, TkltgtT0 usando o mesmo princípio
do algoritmo original (controle dos valores de
sinal oposto). Para isto, cada token carrega 2
valores, Ti.val1 e Ti.val2
T0
T1
T2
T3
T0
T0
T1
val1
val1
val2
val2
val2
val1
M
M
Algoritmo original
Algoritmo modificado
Em M0 processo detecta perda de T0 (através de
T1), ou vice-versa, em M1 de T1 e T2,
etc. Mesmo se restar apenas um unico token,
digamos T0, será possível identificar perda de (e
regenerar) tokens T3 e T1. Mas cuidado
re-geração de tokens deve ser feita em um único
processo, por exemplo, quando detectado pelo
token à esquerda.
15Algoritmo de Token em Árvores
- A fim de evitar que um token seja transferido
independente de haver uma requisição (ex.
topologia de anel), impõe-se uma estrutura de
árvore no conjunto de processos (raiz o atual
detentor do token). - Ideia básica do Algoritmo de Raymond89
- o processo que está com o token é a raiz
- cada processo mantém uma referência (curr_dir)
do seu vizinho mais próximo da raiz. - cada vez que o token é transferido, a árvore é
atualizada - processo que quer entrar na CS envia mensagem
REQ para vizinho indicado por curr_dir - este vizinho gera outro REQ (em seu nome), que
envia para o seu curr_dir (somente 1ª vez) - processos intermediários armazenam requisições
pendentes em fila (as cabeças das filas em cada
processo intermediário indicam o caminho do token
até o requisitante)
Raymond89 Raymond, K. A tree-based Algorithm
for Distributed Mutual Exclusion, ACM
Transactions on Computer Systems, vol.7, no. 1,
1989.
16Algoritmo de Raymond
Exemplo (? indica curr_dir)
A
B
REQ D
D faz requisição
C
D
(D)
17O Algoritmo de Raymond
Variáveis em cada processo Pi bool token //
true, se Pi é detentor do token bool InCS //
true, se Pi esta na seção crítica Addr
curr_dir // referência para vizinho na direção
do detentor do token AddrQueue reqQ // fila que
contém os endereços dos vizinhos com //
requisições pendentes // obs operação rem
remove e retorna o 1o da fila) when EnterCS if
(token FALSE) if empty(reqQ)
send(curr_dir, REQ me) reqQ.add(me)
receive(any, TOKEN) //wait until token to enter
CS InCS true when ExitCS InCS
false if (!empty(reqQ)) curr_dir
reqQ.rem() send(curr_dir, TOKEN)
token false if !empty(reqQ) send(
curr_dir, REQ me)
18Algoritmo de Raymond
MonitorCS loop when recvd (sender, REQ) gt
if (token TRUE) if (InCS)
reqQ.add(sender) else curr_dir
sender send(sender, TOKEN) token FALSE
else // token FALSE if (empty(reqQ))
send (curr_dir, REQ me)
reqQ.add(sender) when
recvd(sender, TOKEN) gt curr_dir
reqQ.rem() if (curr_dir me) token
TRUE else // repassa token na direção de
requisitante send(curr_dir, TOKEN)
if (!empty(reqQ)) send (curr_dir, REQ me) //
se houver gt1 na fila endloop
Cada processo Pi executa também uma thread,
MonitorCS, para repassar REQs e TOKENs
19Algoritmo de Raymond
- Qual é o modelo de sistema?
- Sincronismo?
- Topologia de interconexão?
- Canais de comunicação?
- Nós?
- Sist. assíncrono
- Grafo (não direcionado) conexo qualquer
- Seguros e confiáveis
- Sem falha
20Compressão de Caminhos (Path Compression)
- O principal problema do algoritmo de Raymond é
que o token precisa ser passado por vários
processos intermediários até chegar ao
requisitante (isto se deve à estrutura logica
fixa imposta aos processos por curr_dir) - em vez disto, pode-se fazer com que a árvore
tenha uma forma arbitrária e dinâmica, à medida
que requisições vão sendo repassadas pelos
processos. - Isto é realizado no Algoritmo de Li e Hudak
(1989), usado para garantir a coerência de
páginas em memória virtual distribuída.
LiHudak89 K.Li e P.Hudak. Memory Coherence in
shared virtual memory systems ACM Transactions on
Computer Systems, 7(4), 1989.
21Compressão de Caminhos (Path Compression)
- A ideia basica do Algoritmo de LiHudak89
- processo requisitante Pr manda msg (REQ Pr) para
seu vizinho indicado por curr_dir ( endereço do
detentor do token ou do último a requisitar) - quando processo Q recebe (REQ Pr)
- se Q estiver com o token (e não estiver na SC),
então passa o token diretamente para Pr, - se não estiver com o token, faz um forward de
(REQ Pr) para Q.curr_dir (mas modifica o próprio
Q.curr_dir para apontar diretamente para o Pr) - portanto, se uma requisição passar por vários
intermediários, o novo curr_dir destes todos irá
apontar para o próximo futuro detentor do
token. - Enquanto o futuro detentor do token Pr não
recebe o token, este pode receber outras
requisições, que serão tratadas quando este sair
da SC. - Obs Junto com o token vai a lista de
requisições pendentes - Ao receber o token, um nó faz um merge de sua
lista com a lista vinda com o token.
22Compressão de Caminhos (Path Compression)
Exemplo A faz requisição, mas surgem outras
requisições antes de A receber token.
D
D
D
()
(A,E)
(A,E)
REQ E
REQ A
C
E
E
E
C
C
TOKEN, E
REQ A
B
B
B
REQ B
REQ A
(B) ? (E,B)
A
(B)
A
A
- B e C trocaram curr_dirA
- B envia REQ para A
D envia o token com lista de pendentes,
atualizadas em A
23Compressão de Caminhos (Path Compression)
- Problema à medida que o número de processos
requisitantes cresce, a lista enviada com o token
também aumenta - A complexidade de espaço (tamanho de mensagem) é
O(N), e portanto o algoritmo não é escalável. - Solução manter uma lista encadeada entre os
processos requisitantes (usando um ponteiro
adicional next) - Seja Pu o processo mais recente a ter requisitado
o token - um novo requisitante Pn seta nextNIL e envia o
seu pedido para curr_dir - pedido é repassado pelos processos
intermediários ao longo do caminho definido por
curr_dir na direção de Pu - em cada intermediário, curr_dir é atualizado
para Pn - ao chegar em Pu, este seta curr_dir Pn e next
Pn - quando Pu sair da CS, irá saber para onde mandar
o token (next)
24Exemplo Compressão de Caminhos
B
B
C
C
?
?
REQ D
D
A
D
A
?
?
REQ D
Seja C o último que requisitou token D seta
next? e envia REQ D
A repassa REQ D e troca curr_dir
B
C
B
C
REQ D
?
D
A
D
A
?
?
B repassa REQ D e troca curr_dir
C (ultimo requisitante) seta next e curr_dir
Legenda processos amarelos estão requisitando
SC curr_dir next
25Compressão de Caminhos (Path Compression)
Variáveis em cada processo Pi bool token //
TRUE sse Pi é detentor do token bool InCS //
TRUE sse Pi esta na seção crítica IsRequesting //
TRUE sse Pi está requisitando a SC curr_dir //
dica atual sobre o processo no final da fila de
espera next // o próximo processo a receber o
token, ou NIL, Pi é o último
when EnterCS IsRequesting TRUE if (!token)
// não possui o token send(curr_dir, REQ
me) curr_dir me next NIL wait
until (tokenTRUE) to enter CS InCS true
when ExitCS InCS FALSE IsRequesting
FALSE if next ! NIL send(next,
TOKEN) // envia o token para processo next
token false next NIL
26Compressão de Caminhos (Path Compression)
MonitorCS loop when recv (sender, REQ) gt
if (IsRequesting TRUE ) // Pi
requisitou o token if (next NIL) next
sender else send(curr_dir, REQ,
sender) elseif (token TRUE) // Pi não
requisitou o token token FALSE
send(sender,TOKEN, sender)
else // Pi não está com token nem
requisitou send (curr_dir, REQ sender)
curr_dir sender when
receive(sender, TOKEN) gt token TRUE
endloop
27Algoritmo de Li Hudack
- Qual é o modelo de sistema?
- Sincronismo?
- Topologia de interconexão?
- Canais de comunicação?
- Nós?
- Sist. assíncrono
- Grafo (não direcionado) completo
- Seguros e confiáveis, e FIFO
- Sem falha, e encaminhamento FIFO das mensagens
Qual é o problema se encaminhamento não for FIFO?
Dica considere que outro nó E (ligado a D)
requisitou a seção crítica logo depois que D
enviou o seu req D, mas que req E utrapassa req
D ao longo do itinerário A-B-C. (alguns terão
curr_dir para D, outros para E).
28Algoritmos baseados em Tokens
- Principais Diferenças das três categorias
- Token Circulante
- ordem de repasse previamente definida
- atendimento independente da ordem de requisição
- existe um overhead intrínseco independente do
número de requisições - custo máximo N-1 mensagens, custo médio N/2
mensagens - Estrutura fixa de Árvore
- caminho de repasse definido pela árvore e pela
direção do detentor do token - atendimento na ordem de requisição (a menos de
atrasos na transmissão de req) - custo número de saltos por requisição O(log N)
mensagens - e tamanho da mensagem O(N)
- Estrutura dinâmica de Árvore
- caminho de repasse definido dinamicamente
- atendimento na ordem de requisição (definida
pelo ponteiro next) - custo número de saltos por requisição O(log N)
mensagens e - tamanho da mensagem O(1)
29Algoritmos baseados em Timestamp
- Sejam N processos em uma topologia de grafo
completo - Idéia Central
- um processo só entra na sessão crítica se obtém
o consentimento de todos os demais processos
(?consenso) - usa-se broadcast ? todos os processos
participantes têm uma visão consistente das
requisições - usa-se o relógio lógico de Lamport para
estabelecer uma ordem total dos pedidos - processo só envia resposta (OK) para uma
requisição recebida se esta é anterior a
requisição de sua própria aplicação (se houver) - então, se dois (ou gt2) solicitarem ao mesmo
tempo, só um deles receberá a OK de N-1 processos
30Algoritmos baseados em Timestamp
- Apresentaremos aqui o Algoritmo de Ricart
Agrawala81, que usa o conceito de Relógios
Lógico de L. Lamport - Funcionamento básico do Algoritmo
- processo requisitante Pr difunde um (REQ, ts)
para todos os demais processos Pi - se o processo Pi tem um pedido pendente
anterior ao ts recebido, (ou está na SC) então
adia a resposta, senão retorna um REPLY para Pr - quando Pr recebeu REPLY de todos os Pis,
sabe-se que não existem outras requisições
anteriores, e Pr pode entrar na SC - ao sair da SC, Pr envia todos os REPLYs
pendentes (e.g. de requisições não respondidas) - Algoritmo garante
- acesso exclusivo à Sessão Crítica
- acesso justo à SC (segundo a ordem total
estabelecida)
31Algoritmo de Ricart Agrawala
Replies_pending1
P1
Rep
Req, TS
Req, TS
P2
P4
Req, TS
Rep
Replydeferred1T
P3
- se P4 está na sessão crítica (ou fez requisição
anterior a P1), P4 deixa - de responder à requisição de P1
- P1 saberá que pode entrar na SC assim que tiver
recebido os replies de todos os demais processos
32Algoritmo de Ricart Agrawala
- O Modelo de sistema
- sincronismo
- conjunto/topologia de interconexão?
- canais de comunicação
- nós
- sistema assíncrono
- grupo fixo de processos, grafo completo
- comunicação é confiável e segura
- processos sem falha
- Propriedades do Algoritmo
- simplicidade e simetria textual
- para entrar na SC, precisa-se trocar 2(N-1)
mensagens - como todas as requisições e liberações de SC são
difundidas entre todos os processos, estes
compartilham a mesma visão da lista de
prioridades - A confiabilidade da comunicação é essencial.
Por que? - O uso do relógico lógico é fundamental Por que?
33O Algoritmo de Ricart Agrawala
Variáveis do processo Pi (assumindo M
processos) TS current_time // current Lamport
time TS my_timestamp // timestamp do próprio
pedido int replies_pending // contador dos
replies que precisa receber bool is_requesting //
TRUE ? Pi está requisitando entrada na SC bool
reply_deferredM // para cada processo,
indica se reply foi adiado
Enter_CS() my_timestamp current_time is_requ
esting TRUE replies_pending N -1 send
(all, REQ, my_timestamp) // difusão da
requisição wait until (reply_pending 0)
Exit_CS() is_requesting FALSE for (j1 j
lt N, j) if (reply_deferredj TRUE)
send(j,REPLY, current_time) reply_deferred
jFALSE
34O Algoritmo de Ricart Agrawala
Precisa-se ter uma thread independente para
tratar do recebimento de mensagens dos demais
processos (Monitor_CS), e que compartilha
variáveis com Enter_SC() e Exit_SC().
Monitor_CS() // thread executando em todo
processo Pi loop when recv(j, REQ, req_TS) gt
current_time max(current_time, req_TS)
1 if (not_requesting my_timestamp gt req_TS)
send(j, REPLY, current_time) else
reply_deferredj TRUE when recv(j,
REPLY, rep_TS) gt replies_pending
replies_pending -1 current_time
max(current_time, rep_TS) 1 endloop
35Trabalho Prático (até 4/05)
- Implementar em Neko
- Algoritmo de Tokens circulantes complementares
- Algoritmo de Ricart and Agrawala com tolerância
a mensagens REQ - Simular os dois algoritmos para N 5,10,15
processos e dois diferentes padrões de
solicitação de acesso na Sessão Crítica (alta e
baixa freqência). - Medir e comparar
- o tempo médio de resposta das solcitações
(temporização do Neko) e - o número médio de mensagens por solicitação.
- Escrever um relatório mostrando e discutindo os
dados coletados.
36Algoritmos baseados em Votação
- Ideia Central
- analogia a uma votação política, em que
geralmente um pequeno grupo de eleitores (os
indecisos) decide a eleição - em vez de consultar todos os demais processos, o
requisitante da SC consulta apenas um sub-grupo
de processos, e - caso obtenha todos as confirmações, pode entrar
na SC, senão espera - principal vantagem reduz o número de mensagens
- Apresentaremos o algotitmo proposto por
Maekawa85
Maekawa85 A ?N Algorithm for Mutual Exclusion
in Decentralized Systems, ACM Transactions on
Computer Systems, Vol 3, No. 2.
37Algoritmos baseados em Votação
- Seja P1, P2, , PM o conjunto de processos
- O conceito de distrito (coterie)
- A cada processo P está associado um distrito (
subconjunto de processos) SP - Tal que Pi, Pj, ? k,m, tal que Pi ? Sk, Pj ?Sm e
- Sk ? Sm ? ?
- O conjunto de distritos Si deve ser escolhido
assim (sejam i,j 1,..,M ) - Pi ? Si // o processo pertence ao seu distrito
- Si ? Sj ? ? // há pelo menos 1 processo comum em
2 distritos - E se possível respeitando
- ?Si ? k // distritos devem ter número igual de
elementos - Cada Pj pertence a D distritos Si
38Exemplo
P1
P2
S1 p1,p2, p3 S2 p1, p2, p4 S3 p1, p3,
p4 S4 p2, p3, p4
P4
P3
- Cada Pi pertence a dois distritos ? D 2
- Cada distrito tem três elementos ? k 3
- Requisito essencial
- Para Si ? Sj ? ?
39Exemplo
- Considere N 7 processos
- Como voce construiria os distritos?
Mas será que essa é a melhor escolha para os
distritos? Que minimiza o K?
40Algoritmos baseados em Votação
- Maekawa mostrou que a solução ótima para N
distritos (que minimiza k e permite garantir a
exclusão mútua) é dada por k ? ?M e Dk - Argumentação
- Cada distrito contém k processos que por sua vez
podem pertencer a D -1 outros distritos. Logo o
número maximo N de distritos que podem ser
construídos é - N (D-1) k 1. Dados N, k e D, como cada
processo pode estar em D distritos e cada
distrito tem k elementos, o número máximo de
distritos é DN/k. Se queremos ter exatamente N
distritos, então N DN/k ? D k. - Ou seja N (k - 1) k 1, ou k ? ?N
41Algoritmos baseados em Votação
- No caso geral (para qualquer N) não é trivial
achar os distritos Si ótimos. Uma aproximação é
usar k O(?N) colocar os N processos em uma
matriz (?N x ?N) e usar como Si os processos da
linha e da coluna que contenham Pi . (Neste caso
k ? 2 ?N)
Note ?S4 ? 5 P4 ?S4,S1,S7,S5,S6 D 5
- O algoritmo naïve
- para entrar na SC, um processo Pi envia REQ para
todos em Si - cada processo em Si responde com YES, caso já não
tenha dado o seu voto para outro pedido - ao sair da SC, Pi envia RELEASE para todos em Si
- Problema!
Possibilidade de deadlock, pois não há garantia
de que todos elementos em Si irão receber todos
os REQs na mesma ordem
42Situação de Deadlock
- P2 recebe REQ1, seguida de REQ4 e dá voto a P1
- P3 recebe REQ4, seguida de REQ1e dá voto a P4
- P1 fica aquardando OK de P3
- P4 fica aguardando OK de P2
P1
P2
P3
P4
REQ1
REQ4
- Precisa-se de
- uma forma para decidir qual requisição é a
anterior - Permitir que processos re-atribuam os seus votos
43Algoritmos baseados em Votação
- Solução do problema Sanders8796 usando
Relógios Lógicos - junto com cada REQ envia-se o timestamp de
relógio lógico (Lamport) - se um P ? Si ? Sj ja deu o seu voto para REQi e
depois recebe a REQj com um timestamp menor, P
vai enviar msg INQuire para Pi para anular o seu
voto - Ao receber INQ e se Pi ainda não tiver obtido
todos os votos de seu distrito Si, então Pi
devolve os votos, adiando a sua entrada na SC - Os relógios lógicos impõem uma ordem total aos
pedidos, evitando deadlock, pois - ou a requisição com menor timestamp recebe todos
os votos (talvez depois de reclamar um voto), - ou (se INQ chegar atrasado), o requisitante que
já obteve todos os votos entra na SC - () INQ vem com o timestamp da requisição cujo
voto está sendo reclamado
Sanders87 The information structure of
Distributed Mutual Exclusion Algorithms, ACM
Trans. On Computer Systems, 5(3),
1987. Sanders96 Data Refinement of mixed
specification A Generalization of UNITY, Dept.
of CISE, University of Florida, Tech. Report
96-010
44Algoritmo de Sanders
- Tipos de Mensagem
- REQ TS // pedido de entrada na SC
- RELEASE // notificação de saida da SC
- RELINQUISH // devolução dos votos
- YES // voto para entrada na SC
- INQ TS // solicitação de devolução do voto
Variáveis em cada processo Pi Si // o distrito
associado a Pi InCS // TRUE se Pi está na sessão
crítica curr_TS // o relógio lógico
corrente my_TS // timestamp do próprio pedido de
entrada na SC yes_votes // de processos que
responderam YES has_voted // TRUE se Pi ja deu
seu voto para algum candidato cand // ID do
candidato para o qual foi dado o voto cand_TS //
timestamp do pedido do candidato
cand inquired // TRUE se Pi tentou anular o seu
voto deferredQ // fila de pedidos pendentes, com
as seguintes operações add(P, TS), //
adiciona o par processo, TS da
requisição rem_min() // remove o par
processo,TS tq. TS é o menor valor notempty() /
/ retorna TRUE se a fila não está vazia
45Algoritmo de Sanders
Enter_CS my_TS curr_TS
forall r in Si send(r, REQ, my_TS) // multicast
to coterie while (yes_votes lt ?Si ?)
when recvd(sender,YES) gt yes_votes
yes_votes1 when recvd(sender, INQ, inq_TS) gt
if (my_TS inq_TS) send (sender,
RELINQUISH) yes_votes yes_votes-1
InCS TRUE
Exit_CS InCS FALSE forall r in Si
send(r,REL)
46Algoritmo de Sanders
Monitor_CS loop when recvd(sender, REQ,
req_TS) gt if (NOT has_voted)
send(sender,YES) cand sender cand_TS
req_TS has_voted TRUE else
deferredQ.add(sender, req_TS) if (req_TS
lt cand_TS) (NOT inquired) send(cand,
INQ, cand_TS) // pede anulação do
voto inquired TRUE
when recvd(sender,RELINQUISH) gt
deferredQ.add(cand, cand_TS) s,r_TS
deferredQ.remove_min() // resgata requisição
anterior send(s, YES) cand s cand_TS
r_TS inquired FALSE when
recvd(sender,RELEASE) gt if (deferredQ.notempty
()) s, r_TS deferredQ.remove_min() sen
d(s, YES) cand s cand_TS r_TS else
has_voted FALSE inquired FALSE
endloop
47Exemplo Algoritmo de Sanders
Sejam requisições REQA e REQB, com REQA_TS lt
REQB_TS
A
Deferred (A,4)
Deferred (A,4)
a
b
c
d
YES
INQ
INQ
B
Situação A Apesar da requisição de A ser
anterior a de B, B entra na SC (e ignora todos
os pedidos de INQ) porque já tem os votos de
b,c, d
48Exemplo Algoritmo de Sanders
Ainda REQA e REQB, com REQA_TS lt REQB_TS
A
YES
a
b
c
d
Deferred (B,5)
YES
B
SituaçãoB Como B ainda não entrou na SC, o INQ
de d é tratado, B devolve o voto de d, que envia
o seu voto para A, e A entra na SC.
49O Algoritmo de Sanders
B
A
- Como nem A nem B já receberam todos os YES de
seus distritos, um dos processos na intersecção
irá pedir de volta os seu voto quando conhecer o
pedido do outro processo. Pois PIDA lt PIDB
50Algoritmo de Sanders
- Premissas
- sistema assíncrono
- comunicação é confiável e entrega é FIFO
- comunicação é segura
- requer uma associação prévia entre distritos e
processos (existem outros algoritmos que permitem
uma associação dinâmica) - um processo pode falhar (temporariamente),
contanto que não esteja envolvido em um processo
de votação
51Corretude do Algoritmo
- Argumentação informal de que o algoritmo garante
a exclusão mútua (safety) - Cada processo a cada momento dá o seu voto para
no máximo um processo requisitante mesmo se P
tiver mudado o seu voto, isto só acontece após
ter recebido RELEASE ou RELINQUISH, que
pressupõem que o processo que tinha o voto de P
abriu mão do voto. - Dado que
- Si ? Sj para i,j
- a entrada de um P na SC só ocorre após receber
YES de todos os processos em seu distrito - usando o fato no item 1, e que
- P só libera os votos obtidos ao sair da SC
- tem-se que não é possível que dois ou mais
processos entrem (e permaneçam) simultaneamente
na SC.
52Corretude do Algoritmo
- Argumentação informal sobre a garantia de
vivacidade (liveness), ausência de deadlocks - Suponha (por absurdo) que
- em algum momento exista um (ou mais) processo
bloqueado por ainda não ter obtido todos os votos
de seu distrito e - que ao longo de qualquer possível execução a
partir deste estado, (um estado causalmente
dependente) algum outro processo também bloqueie
tentando entrar na SC (ou seja, o sistema esteja
em deadlock). - Seja A processo bloqueado requisitando a SC com o
menor time-stamp. Este processo está esperando o
voto de um processo P de seu distrito, que deu o
seu voto a um processo, p.ex. do qual recebeu a
mensagem REQ primeiro. Mas como o REQA.TS lt
REQB.TS, P deve ter enviado um INQ para B. A
única razão para B não responder ao INQ é se B já
obteve todos os votos e está na SC. - ? Mas isto contradiz a nossa hipótese de que
nenhum está na SC.
53Corretude do Algoritmo
- Note que o algoritmo não garante atendimento em
ordem! Por que? - Alternativa para evitar deadlocks usado na
prática - processo requisitante Pi espera um determinado
tempo máximo T pelos votos, e se decorrido este
tempo ainda faltarem votos, Pi devolve os votos
já recebidos e tenta mais tarde - Problema
- não funciona para sistemas assíncrononos, e
requer uma escolha cuidadosa de T - Se T for muito pequeno, e houver grande chance de
ocorrência de timeouts, sistema fica em live-lock
e starvation
54Trabalho Práticos (até 6/05)
- Implementar em Neko o Algoritmo de Ricart and
Agrawala visto em aula para 7 processos. - Obs Simular uma aleatoriedade das requisições
- Modificar o Algoritmo de RA para que, em vez de
um processo ter que fazer um REPLY para cada
requisição REQ, que o REPLY de um processo Q seja
considerado válido para todas as requisições, até
que Q mesmo faça uma REQ. Implementar e simular
no DAJ. - Obs URL do DAJ http//www.risc.uni-linz.ac.at/so
ftware/daj/ - O trabalho é individual. Devem ser entregues um
.jar e fontes com documentação.
55Trabalhos Práticos (de 2002.1)
- Usando o simulador DAJ, implementar e simular o
algoritmo de exclusão mútua usando um token
circulante (para N 6) - Modificar o Algoritmo de LiHudak disponibilizado
na página do DAJ, para incluir a lista explicita
de requisições pendentes (usando o ponteiro next)
em vez do envio da lista com o token, e simular o
algoritmo com duas configurações de processos
Lista de Exercícios
- Modificar o Algoritmo de RicartAgrawala para
permitir k entradas simulâneas na sessão crítica. - Seja um conjunto de 9 processos. Pense em uma
escolha apropriada de distritos para o algoritmo
de Maekawa de forma a permitir que no máximo 2
processos possam executar a SC. - Modifique o algoritmo de Raymond para permitir
que a árvore seja reconstruída (e eventualmente o
token seja regenerado) em caso de falha de 1
processo. Assuma que a relação de vizinhança
entre todos os processos está disponível para
cada processo.
56Trabalho 1 Algoritmo de Votação de Sanders
- Implemente (em Neko ) o algoritmo de exclusão
mútua por votação de Sanders - Implemente a definição automática do distrito
para cada processo, e a difusão para os membros
deste distrito. - Teste-o para um número variável de nós n4, 9 e
16, e para padrões de requisição concorrentes - Prazo 28.04
- Referências
- Livro Chow R, Johnson T., pp 361-367
- Artigo Sanders87