sistemas operativos cap. vi sincronização de...

73
6.1 Lições de Sistemas Operativos Sistemas Operativos Cap. VI Sincronização de Threads Prof. José Rogado [email protected] Universidade Lusófona

Upload: others

Post on 26-Jan-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.1 Lições de Sistemas Operativos

Sistemas Operativos

Cap. VI

Sincronização de Threads

Prof. José Rogado

[email protected]

Universidade Lusófona

Page 2: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.2 Lições de Sistemas Operativos

Sincronização de Threads

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 Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.3 Lições de Sistemas Operativos

Concorrência

Vantagens de utilizar execução concorrente

Performance

Economia

Algumas linguagens de programação suportam programação

concorrente de forma nativa (Java, C#)

Existem vários paradigmas de programação concorrente

Não existem modelos gerais

Cada modelo requer uma abordagem específica

Os suportes da concorrência a nível dos sistemas operativos

são geralmente de baixo nível

Implementados no hardware

Page 4: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.4 Lições de Sistemas Operativos

Problemas

Acessos simultâneos (concorrentes) a dados partilhados

por vários fluxos de execução podem gerar

inconsistências

Para manter a consistência dos dados são necessários

mecanismos para garantir a serialização de fluxos de

execução concorrentes

Processos cooperando numa mesma aplicação

usando memória partilhada

Threads dentro de um mesmo processo utilizando as

mesmas varáveis globais

Identificação das secções críticas de código

Acessos concorrentes a dados comuns

Page 5: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.5 Lições de Sistemas Operativos

Analogia: Cruzamento de Tráfego

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 6: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.6 Lições de Sistemas Operativos

shared double balance;

Code for th1 Code for th2

. . . . . .

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

. . . . . .

balance+=amount balance-=amount

balance

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Secção Crítica: exemplo

Page 7: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.7 Lições de Sistemas Operativos

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 th1 Execution of th2

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Secção Critica: problema

Page 8: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.8 Lições de Sistemas Operativos

Secção Crítica (SC): Zona de código que só pode ser utilizada por uma

thread de cada vez, em exclusão mútua

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

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

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

Sem exclusão mútua, o resultado da execução das threads é

indeterminado

São necessários mecanismos do SO para resolver os problemas

levantados pela concorrência

Secção Crítica: definição

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 9: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.9 Lições de Sistemas Operativos

do {

entrada na secção crítica

secção crítica

saída da secção crítica

resto da thread

} while (TRUE) ;

Estrutura de uma Secção Crítica

Secção Crítica

Page 10: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.10 Lições de Sistemas Operativos

Solução do Problema

1. Exclusão Mútua – Se a thread Ti está a executar uma

secção crítica, então nenhuma outra thread pode estar a

executar a mesma secção crítica (SC) em simultâneo

2. Progresso – Só as threads que competem para uma

secção crítica são elegíveis para entrar nessa secção, e a

partir do momento em que uma thread requisita o acesso à

SC este não pode ser adiado indefinidamente

3. Espera Limitada – Depois de uma thread ter requisitado o

acesso à SC, só um número limitado de outras threads

podem entrar na SC antes deste

Page 11: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.11 Lições de Sistemas Operativos

Algumas Soluções Possíveis

Desactivar as interrupções

Só válido em mono-processadores

Kernel não preemptivo

Perca de performance

Utilizar soluções de Software (Peterson)

Soluções complexas válidas para poucas threads

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

Page 12: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.12 Lições de Sistemas Operativos

Desactivar as Interrupções

shared double balance;

Code for th1 Code for th2 disableInterrupts(); disableInterrupts();

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

enableInterrupts(); enableInterrupts();

As interrupções podem ficar desactivadas durante tempos demasiados

longos

Ao sincronizar th1 e th2 está-se a impedir que outras threads possam

continuar a sua execução

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 13: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.13 Lições de Sistemas Operativos

Utilização de uma Variável de Sincronização

shared boolean lock = FALSE;

shared double balance;

Code for th1 Code for th2 /* 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

rru

pt

Inte

rrupt

Inte

rrupt

Espera activa !!

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 14: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.14 Lições de Sistemas Operativos

Falsa “Solução” !!

shared boolean lock = FALSE;

shared double balance;

Code for th1 Code for th2 /* 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;

A thread th1 … testa a variável, e encontra-a com o valor FALSE

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

O A thread th2 … testa a variável e encontra-a também a FALSE

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

Resultado: duas threads na mesma secção crítica…

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 15: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.15 Lições de Sistemas Operativos

Sincronização Hardware

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

Page 16: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.16 Lições de Sistemas Operativos

Instrução Test-and-Set

Definição formal:

boolean atomic TestAndSet (boolean *target)

{

boolean rv = *target;

*target = TRUE;

return rv:

}

Page 17: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.17 Lições de Sistemas Operativos

Detalhe do Test and Set

FALSE m

Primary

Memory

… R3 …

Data

Register CC

Register

(a) Antes de executar TS

TRUE m

Primary

Memory

FALSE R3 =0

Data

Register CC

Register

(b) Depois de executar TS

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

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 18: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.18 Lições de Sistemas Operativos

Solução utilizando Test-and-Set

Variável booleana partilhada lock, inicializada a FALSE.

boolean lock = FALSE;

// Critical section

while (TestAndSet (&lock ))

; // wait

// Enter critical section

lock = FALSE;

// Exit critical section

Page 19: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.19 Lições de Sistemas Operativos

Solução !!

shared boolean lock = FALSE;

shared double balance;

Code for th1 Code for th2 // Acquire the lock // Acquire the lock

while(TAS(&lock)) while(TAS(&lock))

; ;

// Execute critical section // Execute critical section

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

// Release lock // Release lock

lock = FALSE; lock = FALSE;

A thread th1 testa a variável, e encontra-a com o valor FALSE

Mas a instrução TAS mudou o valor para TRUE no mesmo ciclo

A thread th2 testa a variável e encontra-a com o valor TRUE

Espera para entrar na secção crítica

Resultado: uma só thread de cada vez na secção crítica

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 20: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.20 Lições de Sistemas Operativos

Problema

A espera à entrada da secção crítica é feita através de uma

espera activa

Busy wait

Embora não entre na secção crítica, a thread em espera

consome CPU e realiza acessos contínuos à memória

O Test-and-Set implica acesso à variável de sincronização

Esta solução não permite esperas longas

Solução:

Definição de objectos de sincronização mais complexos que

garantam exclusão mútua sem esperas activas

Criação de uma Hierarquia de Sincronização

Page 21: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.21 Lições de Sistemas Operativos

Semáforos Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 22: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.22 Lições de Sistemas Operativos

Definição de Semáforo

A noção de Semáforo foi inicialmente proposta por Edsger

Dijkstra 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 23: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.23 Lições de Sistemas Operativos

Operações sobre um Semáforo

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;

}

Page 24: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.24 Lições de Sistemas Operativos

Ferramenta de Sincronização Genérica

Um semáforo pode ser de contagem (counting) ou binário (mutex)

Counting -> sincronização de n recursos distintos

O valor inicial do semáforo é um inteiro entre 1 e N.

Mutex -> 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);

Page 25: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.25 Lições de Sistemas Operativos

Exemplos de Utilização

semaphore mutex = 1;

thread_create(th_0, 0);

thread_create(th_1, 0);

th_0() { th_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 Nutt

Copyright © 2004 Pearson Education, Inc.

Page 26: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.26 Lições de Sistemas Operativos

Problema do Balanço de Conta

semaphore mutex = 1;

shared int balance;

thread_create(th_0, 0);

thread_create(th_1, 0);

th_0() { th_1() {

. . . . . .

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

wait(mutex); wait(mutex);

balance += amount; balance -= amount;

signal(mutex); signal(mutex);

. . . . . .

} }

Source: Operating Systems, Gary Nutt

Copyright © 2004 Pearson Education, Inc.

Page 27: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.27 Lições de Sistemas Operativos

Implementação de Semáforos

É preciso garantir que não há mais de uma thread a executar wait() e

signal() no mesmo semáforo ao mesmo tempo

A implementação reduz-se ao problema da criar uma secção crítica

para proteger o código internos das funções wait() e signal()

Um 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

Mas a espera não pode ser feita desta forma!

boolean s = FALSE;

// Wait definition

wait(s) {

while(TS(s))

; // wait

}

// Signal Definition

signal(s) {

s = FALSE;

}

Page 28: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.28 Lições de Sistemas Operativos

Espera Activa

Numa implementação básica de semáforos, a operação wait()

implicaria uma espera activa pelo valor positivo do semáforo

Busy wait ou Spin lock

A thread testa o valor e caso este seja menor ou igual a zero, volta

a testar, continuando a concorrer com os outras threads

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

executar!!

atomic wait (S) {

while (S <= 0)

; // busy wait

S = S - 1;

}

Page 29: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.29 Lições de Sistemas Operativos

Semáforos sem Espera Activa

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

wait(): retira a thread da Ready Queue no caso do semáforo estar ocupado

signal(): se houver threads à espera do semáforo, transfere pelo menos um para a Ready Queue (RQ)

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

Ao semáforo é associada uma fila de espera de threads e duas rotinas:

sleep() – retira o processador à thread corrente e coloca-a na em estado waiting fila de espera associada ao semáforo.

wakeup() – retira pelo menos uma thread da fila de espera do semáforo e volta a inseri-la em estado active na Ready Queue.

A nova thread a executar depende dos critérios de scheduling do sistema

Page 30: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.30 Lições de Sistemas Operativos

Implementação do Semáforo Genérico

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 value contém o valor do semáforo (nº de recursos livres)

que é negativo no caso de haver threads em espera

O campo queue permite colocar a thread numa fila de espera no

caso do valor do semáforo ser <= 0

Todos os campos do semáforo são modificados em exclusão

mútua através de instruções Test-and-Set sobre o mutex

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

struct semaphore {

boolean mutex = FALSE;

int value = <initial value>;

struct thread *queue = NULL;

};

Page 31: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.31 Lições de Sistemas Operativos

Implementação com Fila de Espera

struct semaphore {

struct thread *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) {

while(s.queue == NULL)

; // wait

wakeup(s.queue);

}

s.mutex = FALSE;

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 32: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.32 Lições de Sistemas Operativos

Implementação com Fila de Espera

struct semaphore {

struct thread *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) {

while(s.queue == NULL)

; // wait

wakeup(s.queue);

}

s.mutex = FALSE;

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

O wakeup é feito pela primitiva

signal() sempre s.value <= 0 ou

seja, sempre que haja threads

em espera

Neste caso o recurso é

“transferido” da thread que o

liberta para uma das threads

que está à espera em sleep()

Page 33: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.33 Lições de Sistemas Operativos

Exemplo

Semáforo

Th 1 Th 2

Page 34: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.34 Lições de Sistemas Operativos

Exemplo

Semáforo

Th 1 Th 2

Th 2

Page 35: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.35 Lições de Sistemas Operativos

Exemplo

Semáforo

Th 1 Th 2

Page 36: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.36 Lições de Sistemas Operativos

Deadlock e Starvation

Deadlock – duas ou mais threads esperam para sempre por um evento que só uma das threads bloqueados pode produzir

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

T0 T1

wait (S); wait (Q);

wait (Q); wait (S);

. .

. .

. .

signal (Q); signal (S);

signal (S); signal (Q);

Starvation – bloqueamento indefinido: uma thread nunca mais é removida da fila de espera em que está colocada, por ser removida numa ordem diferente da que foi colocada

1 2

3 4

Deadlock !

Page 37: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.37 Lições de Sistemas Operativos

Problemas Clássicos de Sincronização

São problemas que retratam de forma simplificada a essência de

alguns problemas de sincronização existentes em situações reais

Partilha de Dados

Problema do Buffer Limitado

Problema dos Leitores e Escritores

Problema dos Filósofos à Mesa

Page 38: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.38 Lições de Sistemas Operativos

Sincronização: Partilha de 2 Variáveis

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

Page 39: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.39 Lições de Sistemas Operativos

Partilha de 2 Variáveis (Cont.)

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

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 40: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.40 Lições de Sistemas Operativos

Problema do Buffer Limitado

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

Producer Consumer

Data in Data out

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 41: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.41 Lições de Sistemas Operativos

Problema do Buffer Limitado (2)

semaphore mutex = 1;

semaphore full = 0; /* A general (counting) semaphore */

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

buf_type buffer[N];

create_thread(producer);

create_thread(consumer);

producer() {

buf_type *data_in, *buffer;

while(TRUE) {

produce_item(data_in);

/* Get an empty buffer */

wait(empty);

wait(mutex);

buffer = get(emptyPool);

signal(mutex);

copy_buffer(data_in, buffer);

wait(mutex);

release(buffer, fullPool);

signal(mutex);

/* Signal a full buffer */

signal(full);

}

}

consumer() {

buf_type *data_out, *buffer;

while(TRUE) {

/* Get a full buffer */

wait(full);

wait(mutex);

buffer = get(fullPool);

signal(mutex);

copy_buffer(buffer, data_out);

wait(mutex);

release(buffer, emptyPool);

signal(mutex);

/* Signal an empty buffer */

signal(empty);

consume_item(data_out);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 42: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.42 Lições de Sistemas Operativos

Problema do Buffer Limitado (2)

semaphore mutex_empty = 1, mutex_full = 1;

semaphore full = 0; /* A general (counting) semaphore */

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

buf_type buffer[N];

create_thread(producer);

create_thread(consumer);

producer() {

buf_type *data_in, *buffer;

while(TRUE) {

produce_item(data_in);

/* Get an empty buffer */

wait(empty);

wait(mutex_empty);

buffer = get(emptyPool);

signal(mutex_empty);

copy_buffer(data_in, buffer);

wait(mutex_full);

release(buffer, fullPool);

signal(mutex_full);

/* Signal a full buffer */

signal(full);

}

}

consumer() {

buf_type *data_out, *buffer;

while(TRUE) {

/* Get a full buffer */

wait(full);

wait(mutex_full);

buffer = get(fullPool);

signal(mutex_full);

copy_buffer(buffer, data_out);

wait(mutex_empty);

release(buffer, emptyPool);

signal(mutex_empty);

/* Signal an empty buffer */

signal(empty);

consume_item(data_out);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Um mutex por cada pool: melhor

Page 43: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.43 Lições de Sistemas Operativos

Problema dos Leitores e Escritores

Leitores

Escritores

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 44: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.44 Lições de Sistemas Operativos

Problema dos Leitores e Escritores (2)

Reader Reader

Reader Reader

Reader Reader Reader Reader

Writer Writer Writer Writer Writer Writer Writer

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

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

Page 45: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.45 Lições de Sistemas Operativos

Problema dos Leitores e Escritores (3)

Reader Reader Reader

Reader Reader Reader

Reader Reader

Writer Writer Writer

Writer Writer Writer Writer

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

N leitores podem-se executar simultaneamente

Shared

Resource

Page 46: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.46 Lições de Sistemas Operativos

Problema dos Leitores e Escritores (4)

Reader

Shared

Resource

Reader Reader Reader Reader

Reader Reader Reader

Writer Writer Writer Writer Writer Writer

Writer

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Só um escritor se pode executar de cada vez

Quando um escritor está activo, os leitores esperam

Quando há leitores activos, o escritor espera

Page 47: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.47 Lições de Sistemas Operativos

Primeira Solução resourceType *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>;

/* Critical section */

wait(writeBlock);

write(resource);

signal(writeBlock);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

O primeiro leitor bloqueia os escritores

O primeiro escritor bloqueia os leitores

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”

Page 48: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.48 Lições de Sistemas Operativos

Segunda Soluçã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 49: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.49 Lições de Sistemas Operativos

Prioridade aos Escritores int 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);

}

}

1 2

3

4

5

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 50: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.50 Lições de Sistemas Operativos

Problema dos Filósofos à Mesa

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 filósofo só pode comer quando

ficam livres simultaneamente os dois

talheres de cada lado do seu 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

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 51: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.51 Lições de Sistemas Operativos

Problema dos Filósofos à Mesa

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) % 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 52: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.52 Lições de Sistemas Operativos

Primeira Soluçã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

wait(garfo[i]);

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

eat();

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

signal(garfo[i]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

garfo(i)

garfo(i+1)

filosofo(i)

Page 53: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.53 Lições de Sistemas Operativos

Primeira Soluçã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

wait(garfo[i]);

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

eat();

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

signal(garfo[i]);

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Se todos os filósofos acederem simultaneamente aos talheres

do mesmo lado (esquerdo ou direito), cria-se uma solução de

Deadlock

Page 54: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.54 Lições de Sistemas Operativos

Segunda Soluçã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;

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

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

eat();

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

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

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Na primeira escolha, os filósofos de índice par acedem ao garfo

esquerdo, e os de índice ímpar, o garfo direito

Na segunda escolha inverte-se a ordem

Page 55: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.55 Lições de Sistemas Operativos

Segunda Soluçã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;

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

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

eat();

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

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

}

}

So

urc

e:

Op

era

tin

g S

ys

tem

s,

Ga

ry N

utt

Co

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

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 acedem ao garfo

esquerdo, e os de índice ímpar, o garfo direito

Na segunda escolha inverte-se a ordem

Page 56: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.56 Lições de Sistemas Operativos

Problemas de Utilização dos Semáforos

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

wait (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

Page 57: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.57 Lições de Sistemas Operativos

Monitores 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 threads ou processos

Conceito de programação Orientada aos Objectos

Embebida nas linguagens Concurrent Pascal, Java e C#

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ó utilizados pelo monitor

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

monitor mon {

private:

semaphore mutex = 1; // Implícito

. . .

public:

method_i(…) {

wait(mutex); // Implícito

<code for proc_i>;

signal(mutex); // Implícito

};

};

Page 58: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.58 Lições de Sistemas Operativos

Exemplo: 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 59: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.59 Lições de Sistemas Operativos

Balanço de Conta c/ Monitores

monitor sharedBalance;

thread_create(deposit);

thread_create(withdraw);

deposit() {

. . .

sharedBalance.credit(amount);

. . .

}

withdraw() {

. . .

sharedBalance.debit(amount);

. . .

}

Os métodos deposit() e withdraw()

são executados no interior do monitor,

que garante a exclusão mútua da

secção crítica através de uma variável

de sincronização implícita

Page 60: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.60 Lições de Sistemas Operativos

Representação de um Monitor

Page 61: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.61 Lições de Sistemas Operativos

Variáveis de Condiçã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

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

condition_signal (x) – 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 condition_signal() depende da implementação do monitor e do algoritmo de scheduling

Page 62: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.62 Lições de Sistemas Operativos

Um Monitor com Variáveis de Condição

Page 63: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.63 Lições de Sistemas Operativos

Estrutura 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 espera

semaphore mutex = 1; // monitor mutex, initially = 1

semaphore other = 0; // signaling mutex, initially = 0

int 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 = 0

int count = 0; // waiting on x

};

Page 64: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.66 Lições de Sistemas Operativos

Readers & Writers com Monitores

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

pyri

gh

t ©

20

04

Pe

ars

on

Ed

uc

ati

on

, In

c.

Page 65: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.67 Lições de Sistemas Operativos

Hierarquia de Sincronização

Test -and-Set

Spin-lock

Mutex

Semáforo

Monitor Os vários objectos que

descrevemos formam uma

hierarquia de sincronização

Baseada em suporte

hardware

Cada nível utiliza as

funcionalidades do anterior

e estende-a com

capacidades adicionais

Permite garantir a vários

níveis de implementação a

correcção de aplicações

concorrentes

Page 66: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.68 Lições de Sistemas Operativos

Exemplos de Sincronização

Windows

POSIX

Linux

Page 67: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.69 Lições de Sistemas Operativos

Sincronização em Windows

São fornecidos dois mecanismos para exclusão mútua

Mutexes

Critical Sections

Os mutexes são geridos pelo sistema operativo através das

primitivas

HANDLE CreateMutex(attributes, Owner, Name)

WaitforSingleObject(HANDLE, timeout)

ReleaseMutex(HANDLE)

As CriticalSections secções críticas permitem criar zonas de

código protegido sem ter explicitamente de manipular mutexes

InitializeCriticalSection(…)

EnterCriticalSection(…)

LeaveCriticalSection(…)

Page 68: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.70 Lições de Sistemas Operativos

Sincronização POSIX

A sincronização POSIX permite gerir exclusão mútua em

ambientes multiprogramados utilizando a API das pthreads

A API é independente do Sistema Operativo e fornece:

mutex locks

condition variables

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

read-write locks

spin locks

Page 69: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.71 Lições de Sistemas Operativos

API POSIX para Sincronizaçã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 locked que é necessário depois libertar para que uma thread que está em espera possa ser reactivada

Page 70: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.72 Lições de Sistemas Operativos

Sincronização no Kernel Linux

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 71: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.73 Lições de Sistemas Operativos

Exemplo 1: API POSIX

Uma thread produtora recebe dados de um canal de I/O

Para os armazenar, retira um buffer da lista dos buffers vazios,

preenche-o com os dados recebidos e insere-o na lista dos buffers

cheios

Uma outra thread consumidora retira um buffer da lista dos buffers

cheios, envia os dados para tratamento e volta a colocar esse

buffer na lista dos buffers vazios

A thread produtora espera que haja buffers vazios

A thread consumidora espera que haja buffers cheios

Inicialmente os buffers estão todos vazios

Ver ficheiro http://netlab.ulusofona.pt/so/praticas/bound-buffer.c

Page 72: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.74 Lições de Sistemas Operativos

Exemplo 2: API POSIX

Uma thread insere processos em N filas de espera ordenando-os

por prioridade

Uma outra thread retira-os por ordem de prioridade decrescente

Duas actividades concorrentes que criam uma secção crítica ao

poderem modificar simultaneamente as filas de espera

Solução: utilização de um mutex para proteger a secção crítica

Por outro lado, a remoção de processos deve ser comandada por

um evento (sinal) que activa a thread

Solução: utilização de uma variável de condição na qual a thread

de selecção vai esperar

Ver ficheiro http://netlab.ulusofona.pt/so/praticas/proc-sched-sig.c

Page 73: Sistemas Operativos Cap. VI Sincronização de …netlab.ulusofona.pt/so/teoricas/SO-6-Synch-2016.pdfLições de Sistemas Operativos 6.10 Solução do Problema 1. Exclusão Mútua

6.75 Lições de Sistemas Operativos

Fim do Capítulo 6