Please enable JavaScript.
Coggle requires JavaScript to display documents.
Mecanismos de Sincronização (Barreiras (Implementação simples (Usar um…
Mecanismos de
Sincronização
Semáforos
Garantia de corretude do programa
Não há deadlock
Não há starvation
Exclusão mútua satisfeita
Princípios básicos
Singularidade
Espera não ocupada
Atomicidade
Limitações do
uso de semáforo
têm uma maior propensão a erros
não implementam a exclusão mútua diretamente
são considerados primitivas de baixo nível
Monitores
Elementos básicos
variáveis internas acessadas pelos procedimentos
estado interno
um ou mais procedimentos
Somente um processo/thread
pode estar ativo no monitor
de cada vez (thread-safety)
Implementação automática da exclusão mútua
Vantagens do uso de monitores
Maior facilidade na verificação da corretude da implementação
Garantia de exclusão mútua quando do acesso concorrente a um recurso compartilhado
responsabilidade do compilador da linguagem
Todos os métodos de sincronização são confinados no monitor
Estrutura de alto nível que encapsula regiões críticas como procedimentos internos, facilitando a sua manipulação
Risco de
deadlock
quando métodos
sincronizados chamam outros
métodos sincronizados
Variável de condição
Variáveis de condição sempre são utilizadas em conjunto com algum mecanismo de sincronização
(semáforos, monitores ou bloqueios explícitos)
O mecanismo de sincronização é utilizado para
verificar a condição lógica da variável de condição
e decidir pela chamada a wait ou signal
Quando um processo/thread é bloqueado,
ele temporariamente libera o bloqueio a ele garantido
para acessar o recurso compartilhado
Risco de
starvation
devido ao desbloqueio arbitrário de threads quando o método é invocado
Controle de quando um determinado processo/thread deve ter a sua execução suspensa
Barreiras
Solução: as iterações concorrentes devem
aguardar
para iniciar a próxima iteração
Princípios básicos
Suspender a execução de processos/threads do programa em um dado ponto do código
Retomar a execução dos processos/threads suspensos somente quando todos tiverem chegado no ponto do código em questão
Requisito: uma iteração i
depende
de um resultado computado na iteração j
Implementação simples
Usar um
contador
inicializado com o valor zero representando o número de processos/threads na barreira
Cada processo/thread
incrementa o contador
após alcançar a barreira e se
bloqueia
(wait)
Fixar o
número de threads envolvidas
representando as diversas partes
Quando o contador for igual ao número total de processos/threads envolvidos (ou seja, todos chegaram à barreira), eles são todos
liberados
(signal)
Utilização de múltiplos processos/threads para computar de forma concorrente partes disjuntas da solução
Barreiras podem ser ainda úteis uma vez que processos/threads perdem qualquer estado anteriormente armazenado após a sua finalização
...a não ser que tal estado seja armazenado antes de sua finalização
Barreiras são um mecanismo de sincronização coletiva para garantir que processos/threads concluam uma mesma iteração (fase) antes de seguirem juntos para a próxima
Barreiras são tipicamente utilizadas
para operar em
fases
É necessário garantir que só se avança para a próxima fase quando
todos
os processos/threads concluíram suas tarefas
Bloqueios explícitos
Um bloqueio
(lock)
é uma variável para a sincronização por exclusão mútua no acesso a recursos compartilhados
Princípios básicos
O bloqueio é detido por
apenas um
processo/thread, que requisita sua posse executando a operação lock
Se algum processo/thread já for detentor do bloqueio, o processo/thread que requisitou sua posse é
suspenso
O bloqueio é
liberado
pelo processo/thread que o detém executando a operação unlock
Um processo/thread que já detém o bloqueio pode requisitar sua posse novamente (
bloqueio recursivo
) e não é suspenso
Bloqueios podem ser utilizados para sincronizar processos/threads concorrentes de modo que seus efeitos sobre os dados compartilhados sejam
serialmente equivalentes
A intercalação da execução dos processos/threads deve produzir o
mesmo resultado
obtido se eles fossem executado sequencialmente (uma por vez) em alguma ordem
Propósito: evitar problemas de
atualizações perdidas
ou
recuperações inconsistentes
Troca de Mensagens e Canais