Capítulo 6: Sincronização de...

55
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Capítulo 6: Sincronização de Processos

Transcript of Capítulo 6: Sincronização de...

Page 1: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Capítulo 6: Sincronização de Processos

Page 2: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.2 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Módulo 6: Sincronização de Processos

Fundamentos

O problema das Regiões Críticas

Solução de Peterson

Hardware de Sincronização

Travas com Mutex

Semáforos

Problemas Clássicos de Sincronização

Monitores

Exemplos de Sincronização

Alternativas

Page 3: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.3 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Objetivos

Apresentar o conceito de sincronização de processos.

Introduzir o problema da seção crítica, cujas soluções podem ser usadas para garantir a consistência dos dados compartilhados.

Apresentar tanto soluções de software quanto de hardware para o problema da região crítica.

Examinar vários problemas clássicos de sincronização de processos.

Explorar várias ferramentas usadas para resolver problemas de sincronização de processos.

Page 4: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.4 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Fundamentos

Processos podem ser executados simultaneamente

Pode ser interrompido a qualquer momento, completando parcialmente a execução.

Acesso concorrente a dados compartilhados pode resultar em inconsistências.

Manter a consistência de dados requer a utilização de mecanismos para garantir a execução ordenada de processos cooperantes.

Ilustração do problema:

Suponha que seja desejado fornecer uma solução para o problema do produtor-consumidor que utilize todo o buffer. É possível fazer isso tendo um inteiro count que mantém o número de posições ocupadas no buffer. Inicialmente, count é inicializado em 0. Ele é incrementado pelo produtor após a produção de um novo item e decrementado pelo consumidor após a retirada.

Page 5: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.5 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Produtor e Consumidor

/* Produtor:produz um item e coloca em nextProduced */

while (true) {

while (count == BUFFER_SIZE)

; // não faz nada

buffer [in] = nextProduced;

in = (in + 1) % BUFFER_SIZE;

count++;

}

/* Consumidor:consome o item em nextComsumed */

while (true) {

while (count == 0)

; // não faz nada

nextConsumed = buffer[out];

out = (out + 1) % BUFFER_SIZE;

count--;

}

Page 6: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.6 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Condição de Corrida

count++ pode ser implementado como

register1 = count register1 = register1 + 1 count = register1

count– pode ser implementado como

register2 = count register2 = register2 - 1 count = register2

Considere a seguinte ordem de execução com, inicialmente, “count = 5”:

S0: producer execute register1 = count {register1 = 5}S1: producer execute register1 = register1 + 1 {register1 = 6} S2: consumer execute register2 = count {register2 = 5} S3: consumer execute register2 = register2 - 1 {register2 = 4} S4: producer execute count = register1 {count = 6 } S5: consumer execute count = register2 {count = 4}

Page 7: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.7 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema da seção crítica

Considere um sistema de n processos {p0, p1, … pn-1}

Cada processo tem um segmento de código de seção crítica

Os processos podem estar modificando variáveis comuns, atualizndo tabelas, escrevendo arquivos, etc.

Quando um processo estiver em uma seção crítica, nenhum outro processo pode estar nessa mesma seção crítica.

O problema da seção crítica é eleborar um protocolo para resolver isso

Cada processo deve pedir permissão para entrar na seção crítica na seção de entrada, deve seguir a seção crítica até a seção de saída, e então, ir para a seção remanescente.

Page 8: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.8 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Seção crítica

Estrutura geral de um processo Pi típico:

do {

seção de entrada

seção crítica

seção de saída

seção remanescente

} while (TRUE);

Page 9: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.9 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução para o Problema da Região Crítica

1. Exclusão Mútua - Se um processo Pi está executando sua região crítica, então nenhuma região crítica de outro processo pode estar sendo executada.

2. Progresso - Se nenhum processo está executando uma região crítica e existem processos que desejam entrar nas regiões críticas deles, então a escolha do próximo processo que irá entrar na região crítica não pode ser adiada indefinidamente.

3. Espera Limitada - Existe um limite para o número de vezes que outros processos são selecionados para entrar nas regiões críticas deles, depois que um processo fez uma requisição para entrar em sua região e antes que essa requisição seja atendida.

É assumido que cada processo executa em uma velocidade diferente de zero

Nenhuma hipótese é feita referente à velocidade relativa de execução dos N processos.

Page 10: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.10 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Manipulação da Seção Crítica no SO

Duas abordagens dependendo se o kernel é preventivo ou não preemptivo

Preemptivo - permite preempção do processo ao executar no modo kernel

Não Preemptivo - executa até sair do modo kernel, bloquear ou render voluntariamente CPU

Essencialmente livre de condições de corrida no modo kernel

Page 11: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.11 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Tentativas de Solução para a Região Crítica

Inicialmente será considerada uma solução para dois processos

É assumido que as instruções de máquina LOAD (carrega) e STORE (armazena) são atômicas; isto é, não podem ser interrompidas.

Inicialmente são apresentadas duas tentativas e depois a solução

Page 12: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.12 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Tentativa 1

Variáveis compartilhadas:

var turn: (0..1);inicialmente turn = 0

turn = i Pi pode entrar na sua região crítica

Processo Pi

do {

while turn != i

; /* não faz nada */

// REGIÃO CRÍTICA

turn = j;

// SEÇÃO REMANESCENTE

} while (TRUE);

Satisfaz exclusão mútua, mas não progresso.

Page 13: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.13 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Tentativa 2

Variáveis compartilhadas:

var flag: array [0..1] of boolean;inicialmente flag [0] = flag [1] = false.

flag [i] = true Pi pronto para entrar na região crítica

Processo Pi

do {

flag[ i ] = true; while ( flag[ j ] )

; /* não faz nada */

// REGIÃO CRÍTICA

– flag [ i ] = false;

// SEÇÃO REMANESCENTE

} while (TRUE);

Satisfaz exclusão mútua, mas não progresso.

Page 14: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.14 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução de Peterson

Os dois processos compartilham duas variáveis: int turn; Boolean flag[2]

A variável turn indica de quem é a vez de entrar na região crítica.

O vetor flag é usado para indicar se um processo está pronto para entrar na região crítica. flag[i] = true significa que processo Pi está pronto!

Page 15: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.15 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

do {

flag[i] = TRUE;

turn = j;

while ( flag[j] && turn == j)

; /* não faz nada */

// REGIÃO CRÍTICA

flag[i] = FALSE;

// SEÇÃO REMANESCENTE

} while (TRUE);

Algoritmo Para Processo Pi

Page 16: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.16 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sincronização por Hardware

Muitos sistemas fornecem suporte de hardware para código de seção crítica

Sistemas Monoprocessados – podem desabilitar interrupções Código em execução pode executar sem preempção Geralmente muito ineficiente em sistemas multiprocessados

Sistemas Operacionais que usam isso não escalam

Arquiteturas modernas fornecem instruções atômicas especiais de hardware

Atômica = não interrompível Testar uma posição de memória e setar um valor Ou trocar conteúdos de duas posições na memória

Page 17: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.17 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução para problemas de seção críticausando Locks

do {

obtém lock

região crítica

libera lock

região remanescente

} while (TRUE);

Page 18: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.18 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Instrução TestAndSet

Definição:

boolean TestAndSet (boolean *target)

{

boolean ret = *target;

*target = TRUE;

return ret;

}

1. Executa atomicamente

2. Retorna o valor original do valor passado por parâmetro

3. Define o novo valor do parâmetro passado para “verdadeiro”.

Page 19: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.19 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução usando TestAndSet

Variável booleana compartilhada lock, inicializada em FALSE. Solução:

while (true) {

while ( TestAndSet (&lock ))

; /* não faz nada */

// REGIÃO CRÍTICA

lock = FALSE;

// SEÇÃO REMANESCENTE

}

Page 20: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.20 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Instrução Swap

Definição:

void Swap (boolean *a, boolean *b)

{

boolean temp = *a;

*a = *b;

*b = temp:

}

Page 21: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.21 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução usando Swap

Variável booleana compartilhada lock, inicializada em FALSE; Cada processos tem uma variável booleana key local.

Solução:

while (true) {

key = TRUE;

while ( key == TRUE)

Swap (&lock, &key );

// REGIÃO CRÍTICA

lock = FALSE;

// SEÇÃO REMANESCENTE

}

Page 22: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.22 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Exclusão Mútua de espera limitadacom TestAndSet()

do {

waiting[i] = TRUE;

key = TRUE;

while (waiting[i] && key)

key = TestAndSet(&lock);

waiting[i] = FALSE;

// critical section

j = (i + 1) % n;

while ((j != i) && !waiting[j])

j = (j + 1) % n;

if (j == i)

lock = FALSE;

else

waiting[j] = FALSE;

// remainder section

} while (TRUE);

Page 23: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.23 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Travas com Mutex

As soluções anteriores são complicadas e geralmente inacessíveis para programadores de aplicações

Os designers de SO constroem ferramentas de software para resolver o problema da seção crítica

O mais simples é a trava mutex

Para proteger a seção crítica, primeiro adquira a trava com acquire() e depois solte a trava com release(). Variável boleana indicando se a trava está disponível ou não

A chamda para o acquire() e para o release() devem ser atômicas Geralmente implementada através de instruções atômicas do

hardware

Mas essa solução requer espera ocupada Esta trava é, por isso, chamada de spinlock

Page 24: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.24 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

acquire() e release()

acquire() { while (!disponivel)

; /* espera ocupada */

disponivel = false;

}

release() {

disponivel = true;

}

do {

acquire lock

// seção crítica

release lock

// seção remanescente

} while (true);

Page 25: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.25 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Semáforo

Ferramenta de sincronização que não requer espera ocupada (busy waiting) Semáforo S – variável inteira Duas operações padrão modificam S: wait() e signal()

Originalmente chamadas P() e V() Menos Complicada Somente pode ser acessada via duas operações indivisíveis (atômicas)

wait (S) {

while (S <= 0)

; // não faz nada

S--;

} signal (S) {

S++;

}

Page 26: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.26 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Semáforo como uma Ferramenta Geral de Sincronização

Semáforo Contador – valor nele armazenado pode ser qualquer número inteiro.

Semáforo Binário – valor inteiro nele armazenado pode variar entre 0 e 1; pode ser implementado mais simplesmente.

Também conhecido como mutex locks

É possível implementar semáforo contador S como um semáforo binário

Fornece exclusão mútua:

Semaphore mutex; // inicializado em 1

do {

wait (mutex);

// Seção Crítica

signal (mutex);

// restante do código

} while (TRUE);

Page 27: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.27 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Implementação de Semáforo

Deve garantir que dois processos não possam executar wait () e signal () no mesmo semáforo ao mesmo tempo

Daí, a implementação se torna o problema da região crítica na qual o código do wait e signal são colocados em seções críticas.

Pode ter espera ocupada na implementação da região crítica

Código de implementação é menor

Pequena espera ocupada se região crítica está sendo usada raramente

Observe que aplicações podem perder muito tempo em regiões críticas e daí esta não é uma boa solução.

Page 28: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.28 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Implementação de Semáforo sem Espera Ocupada

Associar uma fila de espera com cada semáforo. Cada entrada na fila de espera tem dois itens:

valor (de tipo inteiro)

ponteiro para o próximo registro na lista

Duas operações:

block – coloca o processo que evoca a operação na fila de espera apropriada.

wakeup – remove um processo da fila de espera e coloca-o na fila de processos prontos (ready queue).

Page 29: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.29 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Implementação de Semáforo sem Espera Ocupada (Cont.)

Implementação de wait:

wait(semaphore *S) { S->value--; if (S->value < 0) { adiciona esse processo em “S->list”; block(); }

}

Implementação de signal:

signal(semaphore *S) { S->value++; if (S->value <= 0) { remove o processo P de “S->list”; wakeup(P); }}

Page 30: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.30 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Deadlock (Impasse) e Starvation (Abandono)

Deadlock – dois ou mais processos estão esperando indefinidamente por um evento que pode ser causado somente por um dos processos esperando o evento

Seja S e Q dois semáforos inicializados em 1

P0 P1

wait (S); wait (Q);

wait (Q); wait (S);

. .

. .

. .

signal (S); signal (Q);

signal (Q); signal (S);

Starvation – bloqueio indefinido. Um processo pode nunca ser removido da fila do semáforo em que está suspensa

Priority Inversion – inversão de prioridade. Problema de escalonamento em que um processo de baixa prioridade mantém um lock necessário para um processo de maior prioridade

Page 31: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.31 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problemas Clássicos de Sincronização

Problema do Buffer de tamanho limitado (Bounded-Buffer)

Problema dos Leitores e Escritores

Problema do Jantar dos Filósofos (Dining-Philosophers)

Page 32: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.32 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema do Buffer de Tamanho Limitado

N posições, cada um pode armazenar um item

Semáforo mutex inicializado com o valor 1

Semáforo full inicializado com o valor 0

Semáforo empty inicializado com o valor N

Page 33: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.33 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema do Buffer de Tamanho Limitado (Cont.)

A estrutura do processo produtor

do {

// produz um item

wait (empty);

wait (mutex);

// adiciona o item ao buffer

signal (mutex);

signal (full);

} while (TRUE)

A estrutura do processo consumidor

do {

wait (full);

wait (mutex);

// remove um item do buffer

signal (mutex);

signal (empty);

// consome o item removido

} while (TRUE);

Page 34: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.34 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema dos Leitores e Escritores

Um conjunto de dados é compartilhada entre vários processos concorrentes

Leitores – somente lê um conjunto de dados; eles não realizam nenhuma atualização

Escritores – podem ler e escrever.

Problema – permitir múltiplos leitores ler ao mesmo tempo. Somente um único escritor pode acessar os dados compartilhados ao mesmo tempo.

Dados Compartilhados

Conjunto de dados

Semáforo mutex inicializado em 1.

Semáforo wrt inicializado em 1.

Inteiro readcount inicializado em 0.

Page 35: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.35 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema dos Leitores e Escritores (Cont.)

A estrutura de um processo escritor

do {

wait (wrt) ;

//escrita é feita

signal (wrt) ;

} while (TRUE);

A estrutura de um processo leitor

do {

wait (mutex) ;

readercount ++ ;

if (readercount == 1)

wait (wrt);

signal (mutex);

// leitura é feita

wait (mutex);

readercount - - ;

if (readercount == 0) signal (wrt) ;

signal (mutex) ; } while (TRUE);

Page 36: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.36 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema do Jantar dos Filósofos

Filósofos gastam suas vidas alternando entre pensar e comer

Sem interagir com seus vizinhos, ocasionalmente, eles tentam pegar 2 hashis (um de cada vez) para comer da tigela de arroz

São necesários ambos para comer.

Após comer, eles colocam os hashis novamente na mesa

No caso de 5 filósofos:

Dados compartilhados:

Tigela de arroz (dados compartilhados)

Semáforos chopstick [5] inicializados com 1

Page 37: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.37 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema do Jantar dos Filósofos (Cont.)

A estrutura do Filósofo i:

do {

wait ( chopstick[i] );

wait ( chopStick[ (i + 1) % 5] );

// comer

signal ( chopstick[i] );

signal ( chopstick[ (i + 1) % 5] );

// pensar

} while (TRUE); Qual é o problema desse algoritmo?

Page 38: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.38 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problema do Jantar dos Filósofos (Cont.)

Manipulação da seção crítica

Permita que no máximo 4 filósofos estejam sentados simultaneamente à mesa.

Permita que um filósofo pegue os hashis apenas se ambos estiverem disponíveis (a escolha deve ser feito em uma seção crítica).

Use uma solução assimétrica:

O filósofo de numeração ímpar pega primeiro o pauzinho esquerdo e depois o pauzinho direito.

O filósofo de número par pega primeiro o pauzinho direito e depois o pauzinho esquerdo.

Page 39: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.39 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Problemas com Semáforos

Uso incorreto de operações em semáforos:

signal (mutex) …. wait (mutex)

wait (mutex) … wait (mutex)

Omissão de wait (mutex) ou signal (mutex) (ou ambos)

Deadlock e Starvation podem ocorrer com esses erros.

Page 40: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.40 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Monitores

Uma abstração de alto nível que fornece um mecanismo conveniente e eficaz para a sincronização de processos

Tipo abstrato de dados, variáveis internas são somente acessíveis por código dentro do procedimento

Somente um processo por vez pode estar ativo no monitor Mas não é poderoso o suficiente para modelar alguns esquemas de

sincronização

monitor nome_do_monitor

{

// declaração de variáveis compartilhadas

procedimento P1 (…) { … }

procedimento Pn (…) { … }

codigo_de_inicializacao ( … ) { … }

}

Page 41: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.41 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Visão Esquemática de um Monitor

Page 42: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.42 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Variáveis Condicionais

condicional x, y;

Duas operações são permitidas em uma variável condicional:

x.wait() – um processo que invoca essa operação é suspenso até x.signal().

x.signal() – retoma um dos processos (se houver) que evocou x.wait().

Se não foi executado x.wait() na variável, então essa ação não tem efeito.

Page 43: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.43 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Monitor com Variáveis Condicionais

Page 44: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.44 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Opções de Variáveis Condicionais

Se o processo P chamar x.signal() e o processo Q estiver suspenso em x.wait(), o que deve acontecer a seguir?

Tanto Q quanto P não podem ser executados paralelamente. Se Q for reiniciado, então P deve esperar

Opções incluem:

signal e wait - P espera até que Q deixe o monitor ou aguarde outra condição.

signal e continue - Q espera até que P saia do monitor ou aguarde outra condição.

Ambos têm prós e contras - o implementador deve decidir.

Monitores implementados em Pascal compreendem:

P que executa signal imediatamente sai do monitor, Q é retomado.

Implementado em outras linguagens, incluindo Mesa, C #, Java.

Page 45: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.45 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Solução para o problema dos Filósofos

monitor DP{ enum {THINKING, HUNGRY, EATING} state[5]; condition self [5];

void pickup (int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING) self [i].wait;

}

void putdown (int i) { state[i] = THINKING;

// test left and right neighbors test((i + 4) % 5); test((i + 1) % 5);

}

void test (int i) { if ( (state[(i + 4) % 5] != EATING) && (state[i] == HUNGRY) && (state[(i + 1) % 5] != EATING) )

{ state[i] = EATING ; self[i].signal () ; }

}

initialization_code() { for (int i = 0; i < 5; i++) state[i] = THINKING;

}}

Cada filósofo evoca as operações pickup() e putdown() na seguinte sequência:

dp.pickup (i) // COMERdp.putdown (i)

Page 46: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.46 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Exemplos de Sincronização

Solaris

Windows XP

Linux

Pthreads

Page 47: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.47 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sincronização no Solaris

Implementa uma variedade de travas (locks) para suportar multitarefa, múltiplas threads (incluindo threads tempo real), e multiprocessamento

Usa mutex adaptativos para eficiência quando está protegendo dados de segmentos com código curto

Usa variáveis condicionais e travas leitores-escritores quando seções longas de código necessitam acessar dados

Usa turnstiles para ordenar a lista de threads esperando para adquirir um mutex adaptativo ou uma trava leitor-escritor

Page 48: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.48 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sincronização no Windows XP

Usa máscaras de interrupção para proteger acesso aos recursos globais em sistemas monoprocessados

Usa spinlocks em sistemas multiprocessados

Spinlocking-thread nunca sofrerá preempção.

Também fornece dispatcher objects os quais podem agir como mutexes ou semáforos

Dispatcher objects podem também fornecer eventos

Um evento age de forma parecida com variáveis condicionais

Page 49: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.49 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sincronização no Linux

Linux:

Antes do kernel versão 2.6, desabilita interrupções para implementar seções críticas curtas

Versão 2.6 e posterior, totalmente preemptável

Linux provides:

semáforos

inteiros atômicos

spinlocks

versões de leitores-escritores

Em sistemas de uma única CPU, os spinlocks são substituídos pela habilitação e desabilitação da preempção do kernel

Page 50: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.50 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sincronização em Pthreads

Pthreads API é independente de SO

Ela fornece:

travas mutex

variáveis condicionais

Extensões não portáveis incluem:

travas de leitura-escrita

spinlocks

Page 51: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.51 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Alternativas

Memória Transacional

OpenMP

Linguagens de programação funcional

Page 52: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.52 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Memória transacional Uma transação de memória é uma sequência de operações de

leitura-gravação da memória que são realizadas atomicamente.

void update(){

/* leitura/escrita da memória */}

Page 53: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.53 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

OpenMP

OpenMP é um conjunto de diretivas de compilação e uma API que dão sporte à programação paralela.

void update(int value){ #pragma omp critical { count += value }}

O código do escopo da diretiva #pragma omp critical é tratado comoseção crítica e é realizado automaticamente.

Page 54: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

6.54 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Linguagens de programação funcional

As linguagens de programação funcional oferecem um paradigma diferente das linguagens procedurais, pois não mantêm o estado.

As variáveis são tratadas como imutáveis e não podem mudar de estado depois de terem sido atribuídos um valor.

Há um crescente interesse em linguagens funcionais como Erlang e Scala por sua abordagem no tratamento de condições de corrida.

Page 55: Capítulo 6: Sincronização de Processosjeiks.net/wp-content/uploads/2018/05/SO-Slide-06...Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Objetivos

Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Fim do Capítulo 6