Sistemas Operativos 6ª parte - Sincroniza ção de Processos

71
1 Sistemas Operativos Sistemas Operativos parte parte - Sincroniza Sincronização de Processos ão de Processos Prof. José Rogado [email protected] Prof. Pedro Gama [email protected] Universidade Lusófona Adaptação LIG e Notas por Dr. Adriano Couto

Transcript of Sistemas Operativos 6ª parte - Sincroniza ção de Processos

Page 1: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

1

Sistemas OperativosSistemas Operativos

66ªª parte parte -- SincronizaSincronizaçção de Processos ão de Processos

Prof. José Rogado

[email protected]

Prof. Pedro Gama

[email protected]

Universidade Lusófona

Adaptação LIG e Notas por Dr. Adriano Couto

Page 2: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

2

6.2 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SincronizaSincronizaçção de Processosão de Processos� Objectivos:

� Noções de concorrência, seus problemas e a necessidade de sincronização

� Conhecer os principais mecanismos de sincronização (processos ou threads), seu funcionamento e implementação

� Entender os problemas clássicos da sincronização

� Noções de Concorrência

� Secções Críticas

� Soluções Software

� Hardware de Sincronização

� Semáforos

� Problemas Clássicos de Sincronização

� Monitores

� Exemplos de Sincronização

� Transacções Atómicas

Page 3: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

3

6.3 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ConcorrênciaConcorrência

� Vantagens de utilizar execução concorrente

� Performance

� Economia

� Poucas das linguagens de programação mais divulgadas suportam programação concorrente (Java é uma excepção)

� Existem vários paradigmas de programação concorrente

� Cada modelo requer uma abordagem específica

� Não existem modelos comuns

� Os suportes da concorrência a nível dos sistemas operativos são geralmente de baixo nível

� Próximos do hardware

Já anteriormente se falou das vantagens da concorrência.

Desde 2005 que os abricantes de CPU (Intel e AMD) passarm a apostar na multi-

programação ( multi-processo – multi-thread) como única forma de contínuar a

aumentar o desempenho, uma vez que não é viável continuar a apostar no aumento

das velocidade de relógio.

Ver o site: hhtp://www.go-parallel.com da Intel.

Daremos agora enfâse às soluções para os problemas associados à concorrência.

O aluno deve entender que há vários paradigmas para resolver esses problemas, e

reconhecer os mecanismos básicos subjacentes. Esse mecanismos são geralmente

garantidos (ao nível mais baixo) pelo próprio hardware. Deverá entender porque

razão o hardware tem de fornecer este suporte!

Page 4: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

4

6.4 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ProblemasProblemas

� Acessos simultâneos (concorrentes) a dados partilhados por vários fluxos de execução podem gerar inconsistências

� Processos cooperando num mesma aplicação usando memória partilhada

� Processos acedendo aos mesmos dispositivos de I/O

� Threads dentro de um mesmo processo utilizando as mesmas varáveis globais ou o mesmo I/O

� Para manter a consistência dos dados são necessários mecanismos para garantir a serialização de fluxos de execução concorrentes

Nota: em computação há duas acepções para a palavra serialização: em estruturas de

dados e programação OO é o processo de escrever e ler uma estrutura de dados/objecto

por um canal série (um byte de cada vez); em sistemas concorrentes descreve a

propriedade de as operações efectuadas concorrentemente terem o mesmo resultado

se executadas uma de cada vez. Quando isso não acontece temos um problema...

Page 5: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

5

6.5 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Cruzamento de TrCruzamento de Trááfegofego

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Aqui há um problema se serialização: se os véiculos passam um de cada vez temos

um resultado diferente e melhor.

Os 2 veículos competem/concorrem por uma região comum: querem estar ao mesmo

tempo no mesmo espaço.

Page 6: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

6

6.6 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

shared double balance;

Code for p1 Code for p2

. . . . . .

balance = balance + amount; balance = balance - amount;

. . . . . .

balance+=amount balance-=amount

balance

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

SecSecçção Crão Críítica: exemplotica: exemplo

2 processos manipulam a mesma varável ao mesmo tempo.

Esta é uma situação que está sempre a acontecer nas nossas contas bnacárias!

-- “ao mesmo tempo”? Mas se existir apenas um processador?

Não esquecer a prempção!

Page 7: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

7

6.7 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

load R1, balance

load R2, amount

load R1, balance

load R2, amount

sub R1, R2

store R1, balance

add R1, R2

store R1, balance

Timer interrupt

Timer interrupt

Execution of p1 Execution of p2

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

SecSecçção Critica: problemaão Critica: problema

A partir do momento em que há prrempção a comutação de processos pode ocorrer

em qualquer momento!!!!

Como nenhum dos processos está a efectuar uma chamadade sistema, o Kernel não

sabe que estáo a fazer algo crítico!

Page 8: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

8

6.8 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

� Secção Crítica (SC): Zona de código que só pode ser utilizada por um processo de cada vez, em exclusão mútua

� Existe uma competição entre processos para executar a secção crítica

� A secção crítica pode ter forma diferente (código) em cada processo

� ∴ Não é facilmente detectavel por análise estatística

� Sem exclusão mútua, o resultado da execução dos processos éindeterminado

� São necessários mecanismos do SO para resolver os problemas levantados pela concorrência

SecSecçção Crão Críítica: definitica: definiççãoão

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Criamos o conceito de Seccção Crítica.

Page 9: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

9

6.9 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

do {entrada na secção crítica

secção crítica

saída da secção crítica

resto do processo

} while (TRUE) ;

Estrutura de uma SecEstrutura de uma Secçção Crão Crííticatica

Secção Crítica

Protocolo para usar uma secção crítica: o processo ou thread avisa que quer entrar

e avisa quando sai.

Cabe ao programador garantir este protocolo.

O programador só deve efectuar uma manipulação das variáveis (recursos em geral)

que são objecto de concorrência depois de entrar na secção critica usando o protocolo.

Se o fizer sem respeitar o protocolo irá arder para sempre no inferno de Belzebu, isto

é, a aplicação irá destruir dados de forma aleatória. (Se esse dados representarem

dinheiro haverá lágrimas, baba e ranho na cara dos utilizadores e o programador passará a gestor de hedge funds).

Page 10: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

10

6.10 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SoluSoluçção do Problemaão do Problema

1. Exclusão Mútua – Se o processo Pi está a executar uma secção crítica, então nenhum outro processo pode estar a executar a mesma secção crítica (SC) em simultâneo

2. Progresso – Só os processos que competem para uma secção crítica são elegíveis para entrar nessa secção, e a partir do momento em que um processo requisita o acesso à SC este não pode ser adiado indefinidamente

3. Espera Limitada – Depois de um processo ter requisitado o acesso à SC, só um número limitado de outros processos podem entrar na SC antes deste

Definição de uma SC. Repare-se na afirmação:

”só processos que competem para uma secção crítica são elegíveis

para entrar nessa secção”.

Ou seja não pode entrar quem não mostrou interesse em entrar (1ª zona

colorida no slide anterior)

Page 11: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

11

6.11 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Algumas SoluAlgumas Soluçções Possões Possííveisveis

� Desactivar as interrupções

� Só válido em mono-processadores

� Kernel não preemptivo

� Impacto no desempnho

� Podem perder-se eventos p/ outros processos.

� Utilizar soluções de Software (Peterson)

� Soluções complexas válidas para poucos processos

� Situações de bloqueio difíceis de evitar

� Utilizar soluções de Hardware

� Instruções específicas do processador

� Geralmente utilizadas no kernel

� Fornecidas às aplicações através de APIs de programação de mais alto nível

� Pthreads

� Java

Estas soluções são discutidas a seguir.

Page 12: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

12

6.12 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Desactivar as InterrupDesactivar as Interrupççõesões

shared double balance;

Code for p1 Code for p2disableInterrupts(); disableInterrupts();

balance = balance + amount; balance = balance - amount;

enableInterrupts(); enableInterrupts();

� As interrupções podem ficar desactivadas durante tempos demasiados longos

� Ao sincronizar p1 e p2 está-se a impedir que outros processos possam continuar a sua execução

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Page 13: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

13

6.13 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

UtilizaUtilizaçção de uma Varião de uma Variáável de Sincronizavel de Sincronizaççãoão

shared boolean lock = FALSE;

shared double balance;

Code for p1 Code for p2/* Acquire the lock */ /* Acquire the lock */

while(lock) while(lock)

; ;

lock = TRUE; lock = TRUE;

/* Execute critical sect */ /* Execute critical sect */

balance = balance + amount; balance = balance - amount;

/* Release lock */ /* Release lock */

lock = FALSE; lock = FALSE;

p1

p2

Blo

cked

at while

lock = TRUE

lock = FALSE

Inte

rrup

t

Inte

rrup

t

Inte

rrup

t

Espera activa !!

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Se a interrupção (preempção) ocorrer num momento “favorável”, como represesentado,

a solução funciona. Isto, se p1 mudar a variável antes da interrupção, p2 irá ficar

bloqueado no while, em espera activa, isto é em execução contínua, usando o CPU.

O problema ocorre quando a interrupção ocorre depois do teste e antes da afectação

da variável!!! Lembro-nos que estão em causa várias instruções máquina, apesar

de ser um curto intervalo de tempo!!!

Page 14: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

14

6.14 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Falsa Falsa ““SoluSoluççãoão”” !!!!

shared boolean lock = FALSE;

shared double balance;

Code for p1 Code for p2/* Acquire the lock */ /* Acquire the lock */

while(lock) ; while(lock) ;

lock = TRUE; lock = TRUE;

/* Execute critical sect */ /* Execute critical sect */

balance = balance + amount; balance = balance - amount;

/* Release lock */ /* Release lock */

lock = FALSE; lock = FALSE;

� O processo p1 … testa a variável, e encontra-a com o valor FALSE

� Decide entrar na secção crítica, sai do while e é interrompido

� O processo p2 … testa a variável e encontra-a também a FALSE

� Decide entrar também na secção crítica

� Resultado: dois processos na mesma secção crítica…

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Depois de efectuado o teste no while o processo CORRE para mudar o valor do lock.

Nesta corrida o outro processo pode ganhar, mudando os resultados.

Trata-se de uma corrida crítica (em inglês race condition). Os resultados são

aleatórios e esta solução não tem a propriedade de serialização.

Page 15: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

15

6.15 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ProtecProtecçção doão do LockLock

enter(lock) { exit(lock) {

disableInterrupts(); disableInterrupts();

/* Loop until lock is TRUE */ lock = FALSE;

while(lock) { enableInterrupts();

/* Let interrupts occur */ }

enableInterrupts();

disableInterrupts();

}

lock = TRUE;

enableInterrupts();

}

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

� Utilizam-se dois system calls (enter e exit) que permitem manipular a variável lock de forma segura, desactivando as interrupções antes de mudar o seu valor

� Permite limitar o tempo em que as interrupções estão desactivadas

� Não adaptado para sistemas multiprocessador

Aqui estamos a avisar o kernel (atrvés de uma SysCall) que vamos manipular

uma variável especial.

Mas se não há apio específico do hardware o kernel também vai ter que

desactivar interrupções (para o processador onde a chamada foi efectuada).

Page 16: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

16

6.16 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Hardware Hardware de Sincronizade Sincronizaççãoão

� A maioria dos processadores modernos fornecem instruções específicas para implementar secções críticas

� Atómicas = não interruptíveis

� Dois tipos mais frequentes

� Test-and-set

� Teste de uma variável em memória e modificação do seu valor

� Swap

� Troca (swap) os valores de duas variáveis em memória

A arquitectura de processador x86 possuia a instrução LOCK que garante que

a(s) instruções seguintes são atómicas.

Page 17: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

17

6.17 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

InstruInstruççãoão TestTest--andand--SetSet

� Definição:

boolean TestAndSet (boolean *target)

{

boolean rv = *target;

*target = TRUE;

return rv:

}

Este é a definição equivalente, em C, do TestAndSet.

O hardware garante a atomicidade.

Page 18: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

18

6.18 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Detalhe doDetalhe do Test and SetTest and Set

FALSEm

PrimaryMemory

…R3 …

DataRegister

CCRegister

(a) Antes de executar TS

TRUEm

PrimaryMemory

FALSER3 =0

DataRegister

CCRegister

(b) Depois de executar TS

� TS(m): [Reg_i = memory[m]; memory[m] = TRUE;]

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

No caso dos CPU x86 o opcode LOCK é aplicado às instruções aasembly indicadas

em cima.

Page 19: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

19

6.19 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SoluSoluçção utilizandoão utilizando TestTest--andand--SetSet

� Variável booleana partilhada lock, inicializada a FALSE.� Solução:

while (true) {while ( TestAndSet (&lock ))

; // do nothing

// critical section

lock = FALSE;

// remainder section

}

A SC implementada com o TS têm agora a robustez desejada!

Consegue-se assim implementar uma Secção Crítica.

Page 20: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

20

6.20 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SemSemááforosforosSource: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Este é um mecanismo mais sofisticado para sincronização. Ele permite resolver um

outro tipo de problemas (por exemplo produtores e consumidores).

E veremos como ele é implementável à custa da primitiva de sincronização mais

simples, facultada pelo hardware, que é a SC.

Page 21: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

21

6.21 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

O Problema do Produtor e Consumidor(1)O Problema do Produtor e Consumidor(1)producer() {

while (true) {item = produceItem()

if (itemCount == BUFFER_SIZE) {

sleep()

}putItemIntoBuffer(item)itemCount = itemCount + 1

if (itemCount == 1) {

wakeup(consumer)

}}

}

consumer() {

while (true) {

if (itemCount == 0) {sleep()

}

item = removeItemFromBuffer()itemCount = itemCount - 1

if (itemCount == BUFFER_SIZE - 1) {wakeup(producer)

}

consumeItem(item)}

}

BUFFER_SIZE=5

Page 22: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

22

6.22 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

O problema do Produtor e Consumidor(2)O problema do Produtor e Consumidor(2)

� O produtor depois de produzir um item e incrementar itemCount verifica que o número de itemCount==1 e conclui que o consumidor pode estar a dormir (código a vermelho)

� Porém o consumidor pode ainda não estar a dormir. Ele acabou de fazer o teste, decidiu ir dormir, mas foi comutado antes de chamar o sleep() (código a vermelho)

� Portanto, o wakeup do produtor não encontar ainda ninguém a dormir e perde-se!

� O consumidor finalmente entra no sleep(), mas o respectivo wakeup já foi emitido e não volta a ser repetido (itenCount <>0). Nunca mais acorda!!!

� O código a azul é a situação simétrica e equivalente

� Precisávamos de ter guardado o wakeup!

� O semáforo serve para isso: contabiliza despertares!

Page 23: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

23

6.23 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

DefiniDefiniçção ão de de SemSemááforoforo

� A noção de Semáforo foi inicialmente proposta por EdsgerDijkstra em 1968.

� Um semáforo contém um valor inteiro que só pode ser modificado através de duas operações indivisíveis (atómicas):

� Originalmente chamadas P() e V()

� Proberen (testar) e Verhogen (incrementar) em holandês

� O nome das operações evoluíram para

� wait() e signal()

� Mais de acordo com as suas funcionalidades

Page 24: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

24

6.24 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

OperaOperaçções sobre um Semões sobre um Semááforoforo

� Definição de P() - wait() e V() - signal()

� atomic wait (S) {

while (S <= 0)

; // wait

S--;

}

� atomic signal (S) {

S++;

}

atomic wait (S) {

waitfor (S > 0);

S = S - 1;

}

Define-se a semântica do wait():

• decrementa o semáforo a menos que ele seja 0 e prosegue. Se é 0 bloqueia.

Mostram-se duas hipotéticas implementações uma com espera activa evidente (esq)

outra em que a espera activa poderá ser evitada.

E do signal():

•que apenas incrementa o semáforo.

Repare-se que a atomicidade das operações tem de ser assegurada!!!

Page 25: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

25

6.25 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Ferramenta de SincronizaFerramenta de Sincronizaçção Genão Genééricarica

� Os semáforos podem ser de contagem (counting) ou binários(mutexes)

� Counting -> sincronização de n recursos distintos

� O valor do semáforo é um inteiro entre 0 e N.

� Mutexes -> exclusão mútua de secções críticas

� O valor do semáforo só pode ser 1 ou 0

� O Mutex permite criar exclusão mútua em secções críticas

� Semaphore S; // initialized to 1

� wait (S);

Critical Section

signal (S);

A especilização do semáforo conhecida por mutex é usada para implementar as SC,

pois apresenta para o programador uma API mais homegénea.

Page 26: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

26

6.26 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Exemplos de UtilizaExemplos de Utilizaççãoão

semaphore mutex = 1;

fork(proc_0, 0);

fork(proc_1, 0);

proc_0() { proc_1() {

while(TRUE) { while(TRUE {

<compute section>; <compute section>;

wait(mutex); wait(mutex);

<critical section>; <critical section>;

signal(mutex); signal(mutex);

} }

} }

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Compare-se com o protocolo da SC!

Page 27: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

27

6.27 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema do BalanProblema do Balançço de Contao de Conta

semaphore mutex = 1;

shared int balance;

fork(proc_0, 0);

fork(proc_1, 0);

proc_0() { proc_1() {

. . . . . .

/* Enter the CS */ /* Enter the CS */

wait(mutex); wait(mutex);

balance += amount; balance -= amount;

signal(mutex); signal(mutex);

. . . . . .

} }

Source: Operating Systems, Gary NuttCopyright © 2004 Pearson Education, Inc.

Page 28: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

28

6.28 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Partilha de 2 VariPartilha de 2 Variááveisveis

� Problema:

� Dois processos P1 e P2 trabalham em cooperação

� Utilizam duas variáveis partilhadas x e y para trocar valores

� Os processos têm de se sincronizar para que os valores das variáveis sejam significativos

� Algoritmo:

� P1 actualiza x e continua a execução

� P2 deve ler o valor posto em x por P1 e actualizar y

� P1 deve esperar que P2 actualize y e ler o seu valor

� Sincronização

� Dois semáforos S1 e S2 associados a x e y

� Os semáforos servem de sincronização entre P1 e P2

� Podem também criar um deadlock se forem mal geridos

O problema da comunicação por memória partilhada! Qdo falamos deste mecanismo

de IPC dissemos que tinha o problema da sincronização. Eis a solução!

Numa mesma máquina os processos de uma mesma máquina usam geralmente

memória partilhada e estes mecanismo para se sincronizarem!

Page 29: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

29

6.29 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Partilha de 2 VariPartilha de 2 Variááveis (veis (ContCont.).)

proc_A() {

while(TRUE) {

<compute section A1>;

update(x);

/* Signal proc_B */

signal(s1);

<compute section A2>;

/* Wait for proc_B */

wait(s2);

retrieve(y);

}

}

proc_B() {

while(TRUE) {

/* Wait for proc_A */

wait(s1);

retrieve(x);

<compute section B1>;

update(y);

/* Signal proc_A */

signal(s2);

<compute section B2>;

}

}

semaphore s1 = 0; // Protects x, initially wait

semaphore s2 = 0; // Protects y, initially wait

shared int x, y;

create_thread(proc_A, 0);

create_thread(proc_B, 0);

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Page 30: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

30

6.30 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção de Semão de Semááforosforos

� É preciso garantir que não há mais de um processo a executar wait () e signal () no mesmo semáforo ao mesmo tempo

� A implementação reduz-se ao problema da secção crítica onde os códigos de wait e signal estão dentro da SC

� O semáforo binário pode ser implementado simplesmente com uma instrução Test-and-Set e uma variável binária

� O valor FALSE indica que o semáforo está livre e TRUE ocupado

// Wait definition

boolean s = FALSE;

wait(s) {

while(TS(s))

; // wait

}

// Signal Definition

signal(s) {

s = FALSE;

}

Como é contruído um semáforo? É muito simples! O problema está nos detalhes

e a beleza!

Começamos com o mutex.

Usamos as primitivas que já construimos, o TestAndSet.

Nesta implementação continuamos a fazer espera activa no while.

Page 31: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

31

6.31 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção do Semão do Semááforo Genforo Genééricorico

� A implementação de um semáforo com contador é mais complexa e necessita de uma estrutura com três campos:

� O campo mutex permite criar e proteger a secção crítica correspondente à modificação do valor do semáforo

� O campo hold permite colocar o processo (ou thread) em espera no caso do valor do semáforo ser <= 0

� O campo value contém o valor do semáforo (nº de recursos livres) que é negativo no caso de haver processos em espera

� Os campos mutex e hold são modificados através de instruções Test-and-Set

� Um semáforo binário é um semáforo genérico com valor inicial = 1

struct semaphore {

boolean mutex = FALSE;

boolean hold = TRUE;

int value = <initial value>;

};

Page 32: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

32

6.32 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção do Semão do Semááforo Genforo Genééricoricostruct semaphore {

int value = <initial value>;

boolean mutex = FALSE;

boolean hold = TRUE;

};

shared struct semaphore s;

wait(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value--;

if(s.value < 0) {

s.mutex = FALSE;

while(TS(s.hold))

; // wait

} else

s.mutex = FALSE;

}

signal(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value++;

if(s.value <= 0) {

while(s.hold == FALSE)

; // wait

s.hold = FALSE;

}

s.mutex = FALSE;

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Para o aluno se aperceber da importância dos detalhes é útil seguir a lógica:

•Todo o acesso ao contador tem de ser exclusivo

•Se, no wait, passamos o contador abaixo de =, é porque ele estava em 0.

•Logo devemos bloquear (no hold).

• Mas não podemos bloquear antes de sair da SC,

pois de outra forma paravamos os outros processos também!!!

•Mas isso significa que o TS(s.hold) é fora da SC, logo pode haver comutação!!!

• Temos de acrescentar um teste~adcional ao signal() para verificar se houve estacomutação.!!! É o código na zona colorida.

Page 33: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

33

6.33 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção do Semão do Semááforo Genforo Genééricoricostruct semaphore {

int value = <initial value>;

boolean mutex = FALSE;

boolean hold = TRUE;

};

shared struct semaphore s;

wait(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value--;

if(s.value < 0) {

s.mutex = FALSE;

while(TS(s.hold))

; // wait

} else

s.mutex = FALSE;

}

signal(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value++;

if(s.value <= 0) {

while(s.hold == FALSE)

; // wait

s.hold = FALSE;

}

s.mutex = FALSE;

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� Race condition:

� No caso em que s.value<=0, a thread em signal() tem de aguardar que haja outra threadem espera em s.hold, pois pode ter entrado em wait(), mas estar no ponto indicado

� Assim seria libertado um recurso antes da outra thread esperar, e perdia-se uma sinalização !

Race condition = corrida crítica.

Page 34: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

34

6.34 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Espera ActivaEspera Activa

� Nas implementações de semáforos apresentadas, a operação wait() implica uma espera activa pelo valor positivo do semáforo

� Busy wait ou Spin lock

� O processo testa o valor e caso este seja menor ou igual a zero,volta a testar, continuando a concorrer com os outros processos

� Está a consumir recursos quando não tem condições para se executar

atomic wait (S) {

while (S <= 0)

; // busy wait

S = S - 1;

}

Quando há espera activa (busy wait) estamos a consumir CPU. Poderá ser aceitável

durante um curto intervalo de tempo espacielmente se o processo ou thread tem algo

mais para fazer.

Em SO com mais que em CPU a espera activa pode existir dentro de um wait,

pois o overhead de comutação de processos pode ser superior ao tempo de espera.

Page 35: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

35

6.35 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SemSemááforos sem Espera Activaforos sem Espera Activa

� Uma solução mais correcta é pôr o processo em espera através de invocações explícitas do Scheduler

� wait(): retirar o processo da Ready Queue no caso em que o semáforo esteja ocupado

� signal(): voltar a colocar um dos processo em espera na ReadyQueue sempre que haja processos bloqueados

� Assim a espera num semáforo assemelha-se a qualquer outra operação de espera por recursos (p.ex.: I/O)

� Ao semáforo pode ser associada uma fila de espera de processos e duas rotinas:

� sleep() – retira o processo corrente da RQ e coloca-o na fila de espera associada ao semáforo.

� wakeup() – retira um processo da fila de espera do semáforo e volta a inseri-lo na RQ.

� O processo a eleger depende dos critérios de scheduling do sistema

Vemos como o mecanismo para gestão e escalonamento de processos e threads

é reusável para o Kernel implementar semáforos sem espera activa!

Page 36: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

36

6.36 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção com Fila de Esperaão com Fila de Espera

struct semaphore {

struct proc *queue;

int value = <initial value>;

boolean mutex = FALSE;

};

shared struct semaphore s;

wait(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value--;

if(s.value < 0) {

s.mutex = FALSE;

sleep(s.queue);

} else

s.mutex = FALSE;

}

signal(struct semaphore s){

while(TS(s.mutex))

; // wait

s.value++;

if(s.value <= 0) {

wakeup(s.queue);

}

s.mutex = FALSE;

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� O wakeup é feito pela primitiva signal() sempre s.value <= 0 ou seja, sempre que haja processos em espera

� Neste caso o recurso é“transferido” do processo que o liberta para um dos processos que está à espera em sleep()

Aqui vemos como a implementação das operações do semáforo se faz com recursos

às chamadas de sistema.

Page 37: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

37

6.37 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Deadlock e StarvationDeadlock e Starvation

� Deadlock – dois ou mais processos esperam para sempre por um evento que só um dos processos bloqueados pode produzir

� Se S e Q forem dois semáforos inicializados a 1, a ordem de invocação apresentada conduz a um deadlock

P0 P1

wait (S); wait (Q);

wait (Q); wait (S);

. .

. .

. .

signal (Q); signal (S);

signal (S); signal (Q);

1 2

3 4

Deadlock !

Deadlock é uma situação frequente em aplicações multiprocesso/multithread devido

a erros de concepção e implementação .

Page 38: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

38

6.38 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problemas ClProblemas Cláássicos de Sincronizassicos de Sincronizaççãoão

� Problema do Buffer Limitado ou do Produtor e Consumidor

� Problema dos Leitores e Escritores

� Problema do Jantar de Filósofos

Estes problemas não são meramente alegóricos. Eles exemplificam situações bem

Conbcretas.

Page 39: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

39

6.39 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ProblemaProblema do Buffer do Buffer LimitadoLimitado

Empty Pool

Full Pool

� Um processo produz dados que outro consome

� Utilizam uma pool de buffers para passar dados de um para o outro

� O produtor pode funcionar enquanto houver buffers vazios, e espera quando estiverem todos cheios, até que um esteja vazio

� O consumidor pode funcionar enquanto houver buffers cheios e espera quando estiverem todos vazios, até que um esteja cheio

ProducerProducer ConsumerConsumerData in Data out

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Page 40: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

40

6.40 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ProblemaProblema do Buffer do Buffer Limitado Limitado (2)(2)semaphore full = 0; /* A general (counting) semaphore */

semaphore empty = N; /* A general (counting) semaphore */

producer() {

while(TRUE) {

produce_item();

/* Get an empty buffer */

wait(empty);

put_item_in_buffer();

/* Signal one more item

is available */

signal(full);

}

}

consumer() {

while(TRUE) {

/* Get a full buffer */

wait(full);

remove_item_from_buffer();

/* Signal an empty buffer */

signal(empty);

consume_item();

}

}

• Solução para 1 consumidor e 1 produtor.

•Para mais produtores as funções put_item_in_buffer() concorrem.

•Necessário esclusão mútua

•Para mais consumidores as funções remove_item_from_buffer() concorrem.

•Necessário exclusão mútua.

Page 41: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

41

6.41 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ProblemaProblema do Buffer do Buffer Limitado Limitado (3)(3)

mmúúltiplosltiplos produtores/consumidoresprodutores/consumidoressemaphore mutex = 1;semaphore full = 0;semaphore empty = N;

procedure producer() {while (true) {

produceItem()wait(empty)wait(mutex)putItemIntoBuffer()signal(mutex)signal(full))

}}

procedure consumer() {while (true) {

wait(full)wait(mutex)removeItemFromBuffer()signal(mutex)signal(empty)consumeItem()

}}

Esta implementação assume que existe mais do que um produtor que competem entre

pelos buffers livres e tabém mais do que consumidor que também competem entre si.

Assim torna-se necessário que apenas um produtor aceda ao slot livre; para isso

usa-se o mutex.

Page 42: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

42

6.42 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos Leitores e EscritoresProblema dos Leitores e Escritores

Leitores

Escritores

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Page 43: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

43

6.43 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos Leitores e Escritores Problema dos Leitores e Escritores (2)(2)

ReaderReaderReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReader

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriter

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� Um conjunto de processos realizam acessos a um recurso comum, uns para escrever, outros para ler o seu conteúdo

� Ficheiro, BD, …

� É necessário garantir a coerência dos valores

Shared Resource

Shared Resource

Page 44: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

44

6.44 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos Leitores e Escritores Problema dos Leitores e Escritores (3)(3)

ReaderReaderReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReader

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriter

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� N leitores podem-se executar simultaneamente

Shared Resource

Shared Resource

Page 45: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

45

6.45 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos Leitores e Escritores Problema dos Leitores e Escritores (4)(4)

ReaderReader

Shared Resource

Shared Resource

ReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReaderReaderReader

ReaderReader

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriterWriterWriter

WriterWriter

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� Só um escritor se pode executar de cada vez

� Quando um escritor está activo, os leitores esperam

� Quando há leitores activos, o escritor espera

O estudante deve perceber a natureza do problema e de que forma as primitivas

de sincronização aprendidas servem para o resolver.

Page 46: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

46

6.46 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Primeira SoluPrimeira SoluççãoãoresourceType *resource;

int readCount = 0;

semaphore mutex = 1;

semaphore writeBlock = 1;

create_thread(reader, 0);

create_thread(writer, 0);

reader() {

while(TRUE) {

<other computing>;

wait(mutex);

readCount++;

if(readCount == 1)

wait(writeBlock);

signal(mutex);

read(resource);

/* Critical section */

wait(mutex);

readCount--;

if(readCount == 0)

signal(writeBlock);

signal(mutex);

}

}

writer() {

while(TRUE) {

<other computing>;

wait(writeBlock);

/* Critical section */

write(resource);

signal(writeBlock);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� O primeiro leitor bloqueia os escritores

� O último leitor desbloqueia os escritores

� Qualquer escritor espera por todos os leitores

� Os leitores podem causar starvation dos escritores porque as actualizações “não passam”

� Não é o comportamento mais desejado

Existem 2 soluções: uma dá prioridade aos leitores.

Page 47: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

47

6.47 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Segunda SoluSegunda Soluççãoão

� O algoritmo é modificado para privilegiar os escritores

� Os leitores continuam a poder ler sem exclusão mútua

� Se aparece um escritor e está um leitor activo, o escritor espera

� Se um leitor aparece com um escritor em espera, o leitor espera que o escritor saia

� Se um segundo escritor aparece, tem prioridade sobre os leitores que podem esperar indefinidamente

� Esta solução é complexa e necessita uma implementação cautelosa para evitar deadlocks e starvation

� Veremos uma solução mais robusta baseada em monitores

Page 48: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

48

6.48 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Prioridade aos EscritoresPrioridade aos Escritoresint readCount = 0, writeCount = 0;

semaphore mutex1 = 1, mutex2 = 1;

semaphore readBlock = 1, writeBlock = 1;

create_thread(reader, 0);

create_thread(writer, 0);

reader() {

while(TRUE) {

<other computing>;

wait(readBlock);

wait(mutex1);

readCount++;

if(readCount == 1)

wait(writeBlock);

signal(mutex1);

signal(readBlock);

read(resource);

wait(mutex1);

readCount--;

if(readCount == 0)

signal(writeBlock);

signal(mutex1);

}

}

writer() {

while(TRUE) {

<other computing>;

wait(mutex2);

writeCount++;

if(writeCount == 1)

wait(readBlock);

signal(mutex2);

wait(writeBlock);

write(resource);

signal(writeBlock);

wait(mutex2)

writeCount--;

if(writeCount == 0)

signal(readBlock);

signal(mutex2);

}

}

12

3

4

5

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

a segunda dá prioridade aos escritores.

Page 49: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

49

6.49 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos FilProblema dos Filóósofos sofos àà MesaMesa

� Cinco filósofos estão sentados a uma mesa a comer massa:

� Cada um tem um talher de cada lado, que partilha com o seu vizinho do lado

� Cada um pensa, e só pode comer quando ficam livres os dois talheres de cada lado do prato

� Dois filósofos sentados ao lado um do outro não podem comer ao mesmo tempo.

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Page 50: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

50

6.50 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problema dos FilProblema dos Filóósofos sofos àà MesaMesa

� Para resolver o problema vamos atribuir um índice a cada filósofo, com i variando de 0 a 4

� A cada garfo associa-se um semáforo designado por garfo(i)

� O filósofo i pode comer quando estão livres simultaneamente os semáforos garfo(i) e garfo((i+1) mod 5), ou seja:

� garfo(0) e garfo(1)

� garfo(1) e garfo(2)

� garfo(2) e garfo(3)

� garfo(3) e garfo(4)

� garfo(4) e garfo(0)

Page 51: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

51

6.51 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Primeira SoluPrimeira Soluççãoão

semaphore garfo[5] = (1,1,1,1,1);

fork (filosofo, 1, 0);

fork (filosofo, 1, 1);

fork (filosofo, 1, 2);

fork (filosofo, 1, 3);

fork (filosofo, 1, 4);

filosofo (int i) {

while(TRUE) {

// Think

// Eat

P(garfo[i]);

P(garfo[(i+1) % 5]);

eat();

V(garfo[(i+1) % 5]);

V(garfo[i]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

garfo(i)

garfo(i+1)

filosofo(i)

Page 52: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

52

6.52 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Primeira SoluPrimeira Soluççãoão

semaphore garfo[5] = (1,1,1,1,1);

fork (filosofo, 1, 0);

fork (filosofo, 1, 1);

fork (filosofo, 1, 2);

fork (filosofo, 1, 3);

fork (filosofo, 1, 4);

filosofo (int i) {

while(TRUE) {

// Think

// Eat

P(garfo[i]);

P(garfo[(i+1) % 5]);

eat();

V(garfo[(i+1) % 5]);

V(garfo[i]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� Se todos os filósofos acederem simultaneamente aos talheres do mesmo lado (esquerdo ou direito), cria-se uma solução de Deadlock

Page 53: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

53

6.53 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Segunda SoluSegunda Soluççãoão

semaphore garfo[5] = (1,1,1,1,1);

fork (filosofo, 1, 0);

fork (filosofo, 1, 1);

fork (filosofo, 1, 2);

fork (filosofo, 1, 3);

fork (filosofo, 1, 4);

filosofo (int i) {

while(TRUE) {

// Think

// Eat

j = i % 2;

P(garfo[(i+j) % 5]);

P(garfo[(i+1-j) % 5]);

eat();

V(garfo[(i+1-j) % 5]);

V(garfo[[(i+j) % 5]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

� Na primeira escolha, os filósofos de índice par escolhem o garfo esquerdo, e os de índice ímpar, o garfo direito

� Na segunda escolha inverte-se a ordem

Page 54: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

54

6.54 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Segunda SoluSegunda Soluççãoão

semaphore garfo[5] = (1,1,1,1,1);

fork (filosofo, 1, 0);

fork (filosofo, 1, 1);

fork (filosofo, 1, 2);

fork (filosofo, 1, 3);

fork (filosofo, 1, 4);

filosofo (int i) {

while(TRUE) {

// Think

// Eat

j = i % 2;

P(garfo[(i+j) % 5]);

P(garfo[(i+1-j) % 5]);

eat();

V(garfo[(i+1-j) % 5]);

V(garfo[[(i+j) % 5]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

garfo(0)

filosofo(1)

garfo(2)

filosofo(0)

filosofo(2)

filosofo(3)

filosofo(4)

garfo(3)

garfo(4) garfo(1)

� Na primeira escolha, os filósofos de índice par escolhem o garfo esquerdo, e os de índice ímpar, o garfo direito

� Na segunda escolha inverte-se a ordem

Page 55: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

55

6.55 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Problemas de UtilizaProblemas de Utilizaçção dos Semão dos Semááforosforos

� As operações sobre os semáforos têm de ser usadas correctamente

� Se há troca de ordem, pode haver vários processos na secção crítica

wait (mutex)

// Secção Crítica

signal (mutex)

� Se houver troca de funções, gera-se um deadlock

signal (mutex)

// Secção Crítica

wait (mutex)

� Se houver omissão de uma das funções, um dos dois casos anteriores pode acontecer

� É relativamente frequente em programas complexos acontecerem situações deste tipo que não são fáceis de detectar

� Para evitar estas situações, algumas linguagens utilizam ferramentas de sincronização mais fáceis de utilizar

Motivação para a necessiade de mecanismos mais amigos do programador, que,

não obstante vão ser construídos à custa do que já aprendemos.

Page 56: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

56

6.56 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

MonitoresMonitores� Uma extensão do conceito de semáforo de mais alto nível que fornece

uma interface eficaz e fácil de utilizar para sincronização de threadsou processos

� Conceito de programação Orientada aos Objectos

� Embebida nas linguagens Java e Concurrent Pascal

� Gerida pelo compilador

� O monitor encapsula (esconde) a sua implementação

� Só são acessíveis métodos e dados públicos

� Os métodos e dados privados são só utilizador pelo monitor

� O monitor garante exclusão mútua dos processos que o executam:monitor mon {

private:

semaphore mutex = 1; // Implícito

. . .

public:

proc_i(…) {

P(mutex); // Implícito

<code for proc_i>;

V(mutex); // Implícito

};

};

Esta maéria não vem para o tesde de 6/Janeiro.

Page 57: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

57

6.57 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ExemploExemplo: Shared Balance: Shared Balance

monitor sharedBalance {

private:

double balance;

public:

credit(double amount){

balance += amount;

}

debit(double amount){

balance -= amount;

}

. . .

}

� O problema da partilha da variável balance é resolvido através da declaração de um monitor contendo:

� Uma variável privada balance

� Dois métodos públicos que são executados no interior do monitor com exclusão mútua implícita

Page 58: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

58

6.58 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

RepresentaRepresentaçção de um Monitorão de um Monitor

Page 59: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

59

6.59 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

VariVariááveis de Condiveis de Condiççãoão

� Os monitores fornecem também mecanismos que permitem às threads esperar que se verifiquem condições específicas

� Designam-se por Variáveis de Condição

� Geralmente, são definidas duas operações sobre uma VC x

� x.wait () – permite a uma thread que invoca esta operação ser suspensa até a condição se verificar

� x.signal () – permite a uma thread sinalizar o facto de que a condição se verificou, e activar uma das threads que estiverem em espera

� Não é geralmente garantido que a thread activada seja a que mais tempo tenha esperado

� A forma como as threads são reactivadas por x.signal()depende da implementação do monitor e do algoritmo de scheduling

Page 60: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

60

6.60 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Um Monitor com VariUm Monitor com Variááveis de Condiveis de Condiççãoão

Page 61: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

61

6.61 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Estrutura de um MonitorEstrutura de um Monitor

� Variáveis de Sincronização do Monitor

� Um mutex para exclusão mútua no monitor, inicializado a 1

� Um mutex de sinalização no monitor, inicializado a 0

� Um contador de processos em esperasemaphore mutex = 1; // monitor mutex, initially = 1 semaphore other = 0; // signaling mutex, initially = 0int others_waiting = 0; // number waiting for signaling

� Variáveis de Condição do Monitor: para cada condição éintroduzida uma variável com a seguinte estrutura� Um semáforo de sinalização inicializado a 0� Um contador de processos em espera na variável

struct condvar x {semaphore sem; // initially = 0int count = 0; // waiting on x

};

Page 62: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

62

6.62 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção do Monitor ão do Monitor -- 11

� Variável de condição x:struct condvar x {

semaphore sem; // initially = 0int count = 0; // waiting on x

};

� Operação x.wait:x.wait () {

x.count++;if (others_waiting > 0)

signal (other);else

signal (mutex);wait (x.sem);x.count--;

}

� Operação x.signal:x.signal () {

if (x.count > 0) {others_waiting++;signal (x.sem);wait (other);others_waiting--;

}

� Variáveis de sincronização:semaphore mutex = 1; // monitor mutexsemaphore other = 0; // signaling mutexint others_waiting = 0; // waiting for signaling

� As operações sobre a variável de condição são executadas no interior dos métodos do monitor, com o semáforo de exclusão mutextomado

Page 63: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

63

6.63 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

ImplementaImplementaçção do Monitor ão do Monitor -- 22

� Cada método M do monitor deve obedecer à seguinte estrutura:

wait (mutex);…código de M;…

if (other_waiting)signal (other);

elsesignal (mutex);

� No caso de um método M invocar no seu interior uma operação de espera ou sinalização de uma variável de condição, e havendo outros processos em espera, deve à saída libertar o semáforo de sinalização e não o de sincronização

Page 64: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

64

6.64 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Readers & Writers com Readers & Writers com MonitoresMonitores

monitor readerWriter {

int numberOfReaders = 0;

boolean busy = FALSE;

condition okToRead, okToWrite;

public:

startRead() {

if(busy || (okToWrite.queue())

okToRead.wait();

numberOfReaders++;

okToRead.signal();

}

finishRead() {

numberOfReaders--;

if(numberOfReaders == 0)

okToWrite.signal();

}

startWrite() {

if((numberOfReaders != 0)

|| busy)

okToWrite.wait();

busy = TRUE;

}

finishWrite() {

busy = FALSE;

if(okToRead.queue())

okToRead.signal()

else

okToWrite.signal()

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

py

rig

ht

©2

00

4 P

ea

rso

n E

du

ca

tio

n,

Inc

.

Page 65: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

65

6.65 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

Exemplos de SincronizaExemplos de Sincronizaççãoão

� Solaris

� Windows XP

� Linux

� Pthreads

Page 66: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

66

6.66 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SincronizaSincronizaççãoão emem SolarisSolaris

� Implementa uma grande variedade de locks para suporte de multitasking, multithreading e multiprocessing

� Usa mutexes adaptativos para proteger dados partilhados em segmentos de código curtos

� Comportamento do lock depende de haver ou não vários CPUs

� Utiliza condition variables e readers-writers locks quando as secções de código a proteger são mais extensas

� Utiliza um tipo de fila de espera específico (turnstiles) para ordenar a lista de threads que esperam para adquirir os vários tipos de locks.

Page 67: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

67

6.67 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SincronizaSincronizaççãoão emem Windows XPWindows XP

� Em monoprocessador, utiliza desactivação de interrupções para proteger secção críticas curtas

� Utiliza spinlocks em ambiente multiprocessador

� Fornece dispatcher objects que podem funcionar como mutexes e semáforos

� Os Dispatcher objects também podem gerar eventos

� Funcionam como variáveis de condição

Page 68: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

68

6.68 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SincronizaSincronizaççãoão emem LinuxLinux

� Em monoprocessador, utiliza a desactivação de interrupções para proteger secção críticas curtas

� Utiliza spinlocks baseados em TAS em ambiente multiprocessador

� O kernel é preemptível desde a versão 2.6, mas quando um processo kernel obtém um lock, esta possibilidade é suspensa através da manutenção de um contador do número de preempções em curso (preempt_count) por processo kernel

� Quando as secções críticas de código são extensas, utilizam-se semáforos

� System call futex() “Fast Userspace muTexes” permite a implementação de mutex e semáforos em modo utilizador com recurso mínimo a funções do kernel

http://lxr.linux.no/linux/kernel/futex.c

Page 69: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

69

6.69 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

SincronizaSincronizaççãoão nasnas PthreadsPthreads

� A API das pthreads é independente do Sistema Operativo

� A API fornece:

� mutex locks

� condition variables

� Extensões não dependentes do SO fornecem também:

� read-write locks

� spin locks

Page 70: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

70

6.70 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

API API pthreadspthreads para Sincronizapara Sincronizaççãoão

� Gestão de Mutexes

� pthread_mutex_init (mutex,attr)

� pthread_mutex_lock (mutex)

� pthread_mutex_trylock (mutex)

� pthread_mutex_unlock (mutex)

� Gestão de Condition Variables

� pthread_cond_init (condition,attr)

� pthread_cond_wait (condition,mutex)

� pthread_cond_signal (condition)

� pthread_cond_broadcast (condition)

� Utilização

� pthread_cond_wait deve ser invocada com um mutex locked, a função liberta-o implicitamente

� pthread_cond_signal deve ser invocada com um mutex lockedque é necessário libertar para que uma thread que espera possa recomeçar

Page 71: Sistemas Operativos 6ª parte - Sincroniza ção de Processos

71

Fim do CapFim do Capíítulo 6tulo 6