Chap06 Sincronismo
Chap06 Sincronismo
Na falta de sincronização
- Instruções executas por threads distintas devem
ser consideradas sem ordem ou simultâneas
- Não X < Y, nem Y < X
Exemplo Example
Example: In the beginning...
main()
Y-axis is “time.”
A
Could be one CPU, could
pthread_create()
be multiple CPUs (cores).
foo()
B
A'
• A < •B <AC<B<C
B' • A' <•B'A’ < B’
C • A < •A' A < A’
• C ==• A'C == A’
• C == B'
• C == B’
Seções críticas / Exclusão mútua
¨ Seção crítica: Sequência de instruções que podem gerar
resultados incorretos se executadas simultaneamente
T1 T2 T1 T2 T1 T2
Possibly incorrect
Provalvemente Correct
Correto Correct
Correto
incorreto
5
Quando SC acontece
¨ Um padrão comum
¤ ler – atualizar – escrever
¤ uma variável compartilhada
¤ em código que pode ser executado por threads concorrentes
¨ Variável compartilhada
¤ Variáveis globais e alocadas no heap
¤ NÃO acontece em variáveis locais. Porque?
¤ Cada thread tem a sua pilha
Processo Produtor
Processo Consumidor
Revisitando o problema do Produtor/
Consumidor
¨ Suponha que desejamos alterar a solução apresentada
anteriormente para o problema do Produtor/Consumidor
que preencha todas as posições do buffer
¨ Sintomas típicos
¤ Executo no mesmo conjunto de dados e às vezes imprime 0
e outras imprime 4
¤ Executo no mesmo conjunto de dados e às vezes imprime 4
e às vezes dá erro (crashes)
O problema da seção crítica
¨ Considere um sistema composto por n processos [P0, P1, ... , Pn-1]
Libera seção
crítica para outros
processos
Requisitos de uma solução para o
problema da seção crítica
¨ Exclusão mútua: se o processo Pi está executando código de sua
seção crítica então nenhum outro processo pode estar executando
código de suas seções críticas
do {
flag[i] = true;
while (flag[j]){
flag[i] = false; Pi seta i para false
(espera aleatória); Pj seta j para false
flag[i] = true; Pi seta i para true
Pj seta j para true
}
seção crítica
flag[i] = false ;
seção remanescente
} while (1)
Solução de Peterson
¨ Utilizada apenas para pares de processos
lock()
lock() Two choices:
• Spin
• Block
unlock() • (Spin-then-block)
unlock()
Solução para o problema da seção crítica
utilizando locks
Variáveis compartilhadas:
• boolean waiting[n]
• boolean lock
Exclusão mútua com espera limitada utilizando a
operação TestAndSet()
O primeiro a executar
Variáveis compartilhadas: obtém o lock
• boolean waiting[n]
• boolean lock
Procura o primeiro
que esteja esperando
¨ Princípio básico:
¤ Um processo é suspenso enquanto não obtém permissão
para executar sua RC e é automaticamente “acordado”
através de um sinal
¨ Princípio básico:
¤ Um processo é suspenso enquanto não obtém permissão
para executar sua RC e é automaticamente “acordado”
através de um sinal
typedef struct{
int value;
struct process *L;
} semaforo
Implementação de Semáforos sem espera
ocupada
Problemas de semáforos com fila de espera
Dados
compartilhados
...
¨ Porém há um problema...
Monitores
Produz()
Consome()
T1
Buffer vazio
E agora?
Monitores
Produz()
T1
Consome()
Buffer cheio
E agora?
Solução: Variáveis condicionais
¨ condition x, y;
¨ Duas operações em uma variável condicional
¤ x.wait ()
n um processo que invoca a operação é suspenso
n espera por outro para sinalizar
n possuem filas de espera associadas
¤ x.signal ()
n reinicia um processo que tenha invocado um x.wait ()
(ou não faz nada)
Monitores
Filas associadas às x
condições x e y
y
Dados
compartilhados
...
Produz()
Consome() T1
Fila de threadas
esperando por condição
“not full” ser sinalizada
Buffer cheio
E agora?
Solução para o problema do jantar dos filósofos
Solução para o problema do jantar dos
filósofos