Вы находитесь на странице: 1из 75

Sistemas Operacionais

- Sincronizao de Processos -

O Problema das Regies Crticas

N processos competindo para utilizar os mesmos dados


compartilhados

Cada processo tem um segmento de cdigo onde feito o acesso a


este dado ou recurso compartilhado

Regio crtica

O problema garantir que quando um processo executa a sua


regio crtica, nenhum outro processo pode acessar a sua regio
crtica

Evitar condies de corrida

Vrios processos acessam dados compartilhados concorrentemente e o


resultado da execuo depende da ordem especfica em que ocorre o
acesso ao dado compartilhado

Regio Crtica

Dois processos no podem executar em suas regies crticas ao


mesmo tempo

necessrio um protocolo de cooperao

Cada processo precisa solicitar permisso para entrar em sua


regio crtica

Estrutura geral de um processo


while (true) {
/* cdigo que precede seo crtica */
Seo de entrada
Seo Crtica
Seo de Sada
/* cdigo ps-seo crtica */
}

Regio Crtica

Para solucionar o problema das regies crticas alguns


requisitos precisam ser satisfeitos:

Excluso Mtua: Se um processo Pi est executando sua regio


crtica nenhum outro poder executar a sua regio crtica

Progresso: Nenhum processo fora de sua regio crtica pode


bloquear outro processo

Espera Limitada: Um processo no pode esperar


indefinidamente para entrar em sua regio crtica

Regio Crtica

Cooperao entre processos

Vrios processos podem compartilhar variveis

A escrita deve ser feita de modo exclusivo

Coerncia de dados deve ser mantida

Suponha que os dos dados a e b tenham que se manter iguais (a = b)


P1:
a = a +1; b = b + 1;
P2:
b = b

* 2; a = a * 2;

Cooperao entre processos

Suponha a ordem de execuo (entre processos) e a = b = 1 inicialmente


a = a +1;
b = b

(P1)

* 2; (P2)

b = b + 1;

(P1)

a = a * 2;

(P2)

Final: a = 4 e b = 3

A condio no se mantm regio crtica deve ser definida e excluso


mtua mantida

Cooperao entre processos

Tambm pode ser feita por troca de mensagens

No h compartilhamento de variveis, mas deadlock e starvation

Deadlock: a comunicao deve ser sincronizada

P1

P2

Starvation: quando vrios processos esto se comunicando


P1

P2
P3

Excluso mtua suporte de hardware

Desabilitar Interrupes (realizadas por primitivas do SO)


Desabilita Interrupes
Regio Crtica
Habilita Interrupes

No se deve dar ao processo do usurio o poder de desabilitar


interrupes Se o processo no as reabilita o funcionamento
do sistema est comprometido

As interrupes so desabilitadas em apenas uma CPU

Excluso mtua suporte de hardware

Vantagens

Pode ser aplicvel em qualquer nmero de processos, em um


processador ou vrios, que compartilham memria principal

Pode ser utilizado para dar suporte a uma variedade de sees


crticas, sendo cada uma definida por sua prpria varivel

Desvantagens

Pode degradar o desempenho, pois diminui o grau de


sobreposio de processos dois processos no acessam a RC

Para ambiente multiprocessador, desabilitar interrupo no


garante excluso mtua

Instruo TSL

Instrues especiais de hardware que permitem testar e


modificar uma palavra de memria atomicamente (sem
interrupes)

Instruo Test and Set Lock (TSL)

P
while (lock);
lock = true;

Regio Crtica;
lock = false;

P
while TSL(lock);
Regio Crtica;
lock = false;

Excluso mtua por software

Solues de software com busy wait

Varivel de bloqueio

Comutao alternada

Comutao no alternada

Busy wait

espera ativa ou espera ocupada

Para acessar uma regio crtica, um processo verifica se


pode entrar. Se no puder for, ele espera em um lao
que o acesso seja liberado.

Conseqncia: desperdcio de tempo de CPU.

Varivel de Bloqueio (ou comutao)

indica se a regio crtica est ou no em uso

turn = 0: livre

turn

= 1: ocupada

Tentativa para n processos:


var turn: 0..1
turn := 0
Process Pi:
...
while turn = 1 do {nothing};
turn := 1;
< critical section >
turn := 0;
...

Varivel de Bloqueio

No confirma excluso mtua:

Processos entrar ao mesmo tempo em regio crtica,


pois dois processos podem testar turn antes de set-la
para true
var turn: 0..1
turn := 0
Process Pi:
...
while turn = 1 do {nothing};
turn := 1;
< critical section >
turn := 0;
...

Alternncia Estrita

Assegura a excluso mtua entre dois processos


alternando a execuo entre as regies crticas

A varivel turn indica qual processo est na vez de


executar
PA

PB

while (turn != A);

while (turn != B);

Regio Crtica A;

Regio Crtica B;

turn = B;

turn = A;

Processamento .....

Processamento ....

Um processo fora da sua regio crtica bloqueia a


execuo do outro

Alternncia Estrita

turn global e binrio para dois processos


var turn: 0..1;
P0:
while turn0 do {nothing};
< critical section >
turn := 1;

P1:
while turn1 do {nothing};
< critical section >
turn := 0;

garante a excluso mtua com alternncia na execuo


dos diferentes processos

Acesso a regio crtica, de acordo com a velocidade do


processo

Comutao no Alternada

Assegura a excluso mtua entre dois processos sem


precisar alternar a execuo entre as regies crticas

A varivel turn indica qual processo est na vez de


executar, mas no necessariamente precisa executar

Ento, mais uma informao, em uma varivel do tipo


array

Interested indica se um processo est interessado e pronto para


executar sua regio crtica

Comutao no Alternada

Um processo entra na sua regio crtica se o outro no


estiver interessado

Caso os dois processos estejam interessados o valor de


turn decide qual processo ganha a regio crtica

PA

PB

interested[A] = true;

interested[B] = true;

turn = B;

turn = A;

while (interested[B] && turn==B);

while (interested[A] && turn==A);

< regio crtica >

< regio crtica >

interested[A] = false;

interested[B] = false;

Regio Crtica

Todas as solues apresentadas possuem o problema


da espera ocupada

O processo bloqueado consome tempo de CPU


desnecessariamente

Soluo:

Introduzir comandos que permitam que um processo seja


colocado em estado de espera quando ele no puder acessar a
sua regio crtica

O processo fica em estado de espera at que outro processo o


libere

Vamos olhar mecanismos que no consuma CPU

Semforos

Um semforo uma varivel inteira no negativa, manipulada


atravs

Inicializao

Decremento OU acquire() Ou P() OU Down() OU wait() OU lock(): : pode


bloquear um processo

Incremento OU relase() OU V() OU Up() OU signal() OU unlock(): : pode


desbloquear um processo

As modificaes feitas no valor do semforo so atmicas e no


podem ser interrompidas

Semforos

No caso da excluso mtua as instrues Down e Up funcionam


como protocolos de entrada e sada das regies crticas.

Decremento executado quando o processo deseja entrar na regio


crtica.

Decrementa o semforo de 1

bloqueia outros processos

Incremento executado quando o processo sai da sua regio crtica.

Incrementa o semforo de 1

Desbloqueia processos

Semforos

Um semforo fica associado a um recurso


compartilhado, indicando se ele est sendo usado

Se o valor do semforo maior do que zero, ento


existe recurso compartilhado disponvel

Se o valor do semforo zero, ento o recurso est


sendo usado

wait(S)

signal(S)

S.count --;

S.count++;

if (S.count < 0)

if (S.count <= 0)

bloqueia processo;

desbloqueia processo;

Semforos pontos interessantes

Em geral, no se sabe antes de um decremento, se um


processo ficar bloqueado ou no

Depois de um incremento feito por um processo, um


outro processo pode se desbloqueado, e os dois
comeam a ser executados concorrentemente

No se sabe ao certo qual ganhar uma nica CPU

Ao incrementar um semforo (sinalizar), no se sabe a


priori se h outros processos bloqueados

Semforos binrios

Mais restritos com seus valores 0 e 1

Se o valor do semforo maior do que zero, ento


existe recurso compartilhado disponvel

Se o valor do semforo zero, ento o recurso est


sendo usado

Down(S)

Up(S)

if (S == 0)
bloqueia processo
else
S = S - 1;

if (tem processo na fila)


libera processo
else
S = S + 1;

Semforos
mutex

um semforo binrio

Diferena

chave

um processo que seta o valor para zero do mutex, d um lock,


o processo que deve dar unlock no mutex

Semforo forte X fraco


Se

a fila de processos bloqueados tem ou no tem


poltica FIFO

Semforos
mutex

um semforo binrio

Diferena

chave

um processo que seta o valor para zero do mutex, d um lock,


o processo que deve dar unlock no mutex

Semforo forte X fraco


Se

a fila de processos bloqueados tem ou no tem


poltica FIFO

Semforos: forte X fraco

Processos A, B e C dependem do resultado de D


Resultado de D disponvel

B fica bloqueado

D ganha processador

D produz resultado

Somente
liber-los

para

Semforos

Para excluso mtua usado um semforo binrio


P
Down (mutex);
Regio Crtica;
Up (mutex);

Semforos tambm so usados para implementar a sincronizao


entre os processos

O uso de semforos exige muito cuidado do programador

Os comandos down e up podem estar espalhados em um programa


sendo difcil visualizar o efeito destas operaes

Dados compartilhados protegidos por


semforo

Um Problema Clssico de
Sincronizao

Produtor/Consumidor

Produtor/Consumidor

Processo produtor produz informaes que so


gravadas em um buffer de tamanho limitado

As informaes so consumidas por um processo


consumidor

O produtor pode produzir um item enquanto o


consumidor consome outro

Mas somente um consumidor e um produtor podem


exclusivamente acessar o buffer compartilhado

Produtor/Consumidor

O produtor e o consumidor devem estar sincronizados

O produtor no pode escrever no buffer cheio

O consumidor no pode consumir informaes de um buffer


vazio

Produtor/Consumidor

Exemplo de uma aplicao "Produtor/Consumidor:

Outro exemplo:

um thread (o produtor) grava dados em um arquivo enquanto


outro thread (o consumidor) l dados do mesmo arquivo

enquanto voc digita no teclado/mouse, o produtor coloca


eventos de mouse em uma fila de eventos e o consumidor l os
eventos da mesma fila para trat-los

Em ambos os casos, temos threads que compartilham


um recurso comum

Produtor/Consumidor buffer limitado

Semforo binrio s para excluso mtua (tipo mutex)

O buffer a ter itens produzidos e consumidos tem


tamanho limitado

Tratado como um array circular

Produtor/Consumidor buffer limitado

Semforos n(full) e e (empty)

n conta os espaos cheios no buffer

e conta os espaos vazios no buffer

Se n igual a zero, ento o consumidor deve ser bloqueado

Se e igual a zero, ento o produtor deve ser bloqueado

s um mutex (semforo binrio)

para controle da regio crtica, no caso, o buffer

Produtor/Consumidor buffer limitado

Produtor/Consumidor
Gera item
Mais uma posio do buffer ser usada, logo, decrementa
Entra na RC
Efetivamente, acessa o buffer
Deixa a RC
Incrementa o contador de itens no buffer

Decrementa n, pois item ser consumido


Vai entrar em RC
Consome um item
Libera RC
Incrementa o contador de espaos vazios
Faz algo com o item retirado do buffer compartilhado

Monitores

Semforos so ferramentas importantes para implementar excluso


mtua

Mas pode ser difcil utiliz-los corretamente em um programa

Esto sujeitos a erros de programao

Vimos alguns exemplos de uso que no garantem excluso mtua,


sendo necessrio adicionar outras variveis de bloqueio

Principalmente se necessrio definir mais de uma RC

No existe um controle formal de sua presena


Como tornar o uso de semforos mais fcil/amigvel?

Monitores

um construtor de linguagem de programao que oferece a


funcionalidade dos semforos

maior facilidade de utilizao por parte do programados

no tem em muitas linguagens de programao, mas em Java

codificar as sees crticas como procedimentos do monitor

tornar mais modular

quando um processo precisa referenciar dados compartilhados

chama um procedimento do monitor

Mdulos de linguagens de programao que fornecem uma


funcionalidade equivalente aos semforo

Monitores

O monitor um conjunto de procedimentos, variveis e inicializao


definidos dentro de um mdulo

um processo entra no monitor, chamando um dos seus procedimentos

como se fosse uma classe

A caracterstica mais importante do monitor a excluso mtua


automtica entre os seus procedimentos

Basta codificar as regies crticas como procedimentos do monitor e o


compilador ir garantir a excluso mtua

Como semforos, s um processo pode estar executando no monitor


de cada vez, sendo que outros processos que chamarem o monitor,
ficaro bloqueados

Oferece excluso mtua

Monitores

Variveis compartilhadas podem ser protegidas, especificando-as


atravs do monitor

Um processo pode ser bloqueado quando tentar entrar no monitor,


mas este est sendo utilizado por outro

Quando um processo termina de usar o monitor, tem que liber-lo

Monitores
monitor monitor-name
{
declarao de variveis compartilhadas
procedure P1 () {
...
}
procedure P2 () {
...
}
procedure Pn () {
...
}
{
}

cdigo de inicializao

Monitores

Para implementar a sincronizao necessrio utilizar variveis de


condio, s acessveis dentro do monitor

Variveis de condio

so tipos de dados especiais dos monitores

so operadas por duas instrues Wait e Signal

Wait(C): suspende a execuo do processo, colocando-o em


estado de espera associado a condio C

Signal(C): permite que um processo bloqueado por wait(C) continue


a sua execuo.

Se existir mais de um processo bloqueado, apenas um liberado


Se no existir nenhum processo bloqueado, no faz nada

Monitores

Um processo entra em um monitor,


chamando qualquer um de seus
procedimentos

Um processo est em um monitor,


quando est pronto ou executando

Um ponto de entrada somente,


para garantir excluso mtua

Outros processos ficam em fila de


bloqueados se tentarem entrar no
monitor

ponto de nico de entrada


garante excluso mtua

Monitores

Produtor/Consumidor utilizando
buffer de tamanho limitado

Duas variveis de condio:

notfull TRUE se ainda h espao


notempty TRUE se tem caractere

void producer()!
{!
!char x;!
!while (true){!
!
!produce(x);!
!
!append(x);!
!}!
}
!!
void consumer()!
{!
!char x;!
!while (true){!
!
!produce(x);!
!
!append(x);!
!}!
}!
void main()!
{!
!parbegin (producer,
consumer);!
}!

Monitores
monitor boundbuffer;!
char buffer[N];
!
!/* espao para N itens */!
int nextin, nextout; !
!/* ponteiros para o buffer */!
int count;
!
!
!/* # itens no buffer */!
cond notfull, notempty;
!/* var. de condio p/ sincronizao*/!
void append (char x)!
{!
!if (count == N) cwait (notfull); /* buffer cheio, evitar overflow */!
!buffer[nextin] = x;!
!nextin = (nextin + 1) mod N;!
!count++;
!
!/* mais um item no buffer */!
!csignal (notempty); !/* consumidor em espera pode ser finalizado */!
}!
void take (char x)!
{!
!if (count ==0) cwait(notempty); /* buffer vazio, evite underflow*/!
!x = buffer[nextout];!
!nextout = (nextout + 1) mod N;!
!count --;
!/* menos um item no buffer */!
!csignal (notfull); /* produtor em espera pode ser finalizado */!
}!

Monitores
/* inicializaes no main */!
{!
!nextin = 0; nextout = 0; count = 0; !
}!

Um processo entra em um monitor, chamando qualquer um de seus


procedimentos

Um ponto de entrada somente, para garantir excluso mtua

Outros processos ficam em fila de bloqueados se tentarem entrar no monitor

Monitores - curiosidade

Uma linguagem atual que oferece o uso de monitores Java

cada objeto tem seu prprio monitor

mtodos so colocados em estado de monitor atravs da palavra chave


synchhronized

existe somente uma varivel de condio assim, no precisa ser


explicitamente especificada

mtodos que testam tais variveis so: wait(), notify(), and notifyAll()

wait( ) o respectivo thread vai para bloqueado (estado sleep) at que algum outro thread
que entrou no monitor notify( )

notify( ) acorda o primeiro thread que chamou um wait( ) no mesmo objeto

notifyAll( ) acorda todos os threads que chamaram wait( ) no mesmo objeto, sendo que
a thread de maior prioridade executa primeiro.

Troca de Mensagens

Quando necessrio trocar informaes entre processos que no


compartilham memria

Usado para comunicao e sincronizao

Basicamente usa duas primitivas

send(destino, mensagem)

receive(origem, mensagem)

Estas duas primitivas podem ser facilmente colocadas em


bibliotecas

Uma biblioteca de comunicao que se tornou padro MPI

Troca de Mensagens

Sincronizao

Um processo receptor no pode receber uma mensagem at que esta


tenha sido enviada

Deve se determinar o que acontece com um processo aps executar


um send ou receive

Send quando um send executado existe a possibilidade de bloquear


ou no o processo at que a mensagem seja recebida no destino

Receive quando o processo executa um receive existem duas


possibilidades:

se a mensagem j foi enviada o processo a recebe e continua a sua


execuo

se a mensagem ainda no foi enviada (no foi executado um send() por


algum)

o processo bloqueado at que a mensagem chegue ou

o processo continua a executar e abandona a tentativa de recebimento

Troca de Mensagens

Send e Receive podem ser bloqueantes ou no


bloqueantes

O mais comum send no bloqueante e receive bloqueante

Troca de Mensagens

Endereamento Direto

O processo que envia ou recebe uma mensagem deve


especificar a origem e o destino por endereamento direto

Identificao do processo

O sender sempre especifica a id do recebedor

Receiver

pode especificar a id (comum em aplicaes paralelas)

ou no: comum quando o recebedor oferece servios

Troca de Mensagens

Endereamento Direto - exemplo

Processo printer-server

o cliente que envia mensagem especifica o destinatrio

o servidor, pode receber de qualquer processo

Troca de Mensagens

Endereamento Indireto

As mensagens no so endereadas diretamente entre


processos origem e destino

As mensagens so enviadas para caixas postais so filas/


buffers

mailboxes

Desacopla processo que envia daquele que recebe:

Um para um (one-to-one)

Vrios para um (many-to-one) neste caso o mailbox


referenciado como port

Um para vrios (one-to-many)

Vrios para vrios (many-to-many)

Troca de Mensagens

Vrios para um (many-to-one) pode


representar comunicao cliente
servidor

Broadcast: comunicao umpara-vrios

Troca de Mensagens

Endereamento Indireto

Associao de processos a mailboxes pode ser

Esttico

portas so normalmente associadas a processos estaticamente


Um-para-um geralmente definido estaticamente

Dinmico

Portas so geralmente criadas pelo processo recebedor

Mailboxes so geralmente criadas pelo SO

Troca de Mensagens eExcluso Mtua


Implementao de Excluso Mtua com Processos

processos compartilham um mailbox: box

Inicialmente, box contem uma msg com contedo NULL

Para entrar em regio crtica:

msg um
token

processo tenta receber msg

Se box est vazio processo fica bloqueado

Se tem uma msg, processo recebe msg e entra em RC

Como ficaria um algoritmos

Problema Clssico de Sincronizao

Leitores e Escritores um outro problema clssico

Leitores e Escritores

Existem reas de dados compartilhadas

rea pode ser um arquivo ou bloco da memria principal

Leitores: processos que apenas lem dados destas reas

Escritores: processos que apenas escrevem dados nestas reas

Condies:

Qualquer nmero de leitores pode ler ao mesmo tempo

Apenas um escritor pode acessar a rea por vez

Se um escritor est escrevendo, nenhum leitor poder utiliz-lo

Leitores e Escritores

Ento excluso mtua somente quando escritores estiverem


acessando a rea

Diferenas com o produtor/consumidor:

Leitores s lem e escritores s escrevem (a prpria operao


difere)

Exemplo: catlogo de biblioteca

Vrios podem consultar

S uma bibliotecria pode atualizar

Leitores e Escritores
Verso 1: prioridade aos leitores

Semforo x para acesso a readcount


Se o primeiro leitor a tentar acessar RC, tem
prioridade e o escritor no pode acessar
Se um leitor acessa RC, outros leitores
podem acessar
Para atualizar readcount
Se no tem mais leitor, um escritor pode
acessar RC

S um escritor pode acessar a RC, quando


nenhum leitor estiver acessando

Leitores e Escritores
Verso 1: prioridade aos
leitores

Semforo x para acesso a readcount


Se o primeiro leitor a tentar acessar
RC, tem prioridade e o escritor no
pode acessar
Se um leitor acessa RC, outros
leitores podem acessar
Para atualizar readcount
Se no tem mais leitor, um escritor
pode acessar RC

S um escritor pode acessar a RC,


quando
nenhum
leitor
estiver
acessando

int readcount;!
semaphore x=1; wsem=1;!
void reader()!
{
!while (true){!
!
semWait (x);!
!
readcount++;!
!
if (readcount==1) semWait(wsem);!
!
semSignal (x);!
!
READUNIT();!
!
semWait (x);!
!
readcount--;!
!
if(readcount==0) semSignal (wsem);!
!
semSignal (x);!
!}!
}!
void writer()!
{
!while (true) {!
!
semWait (wsem);!
!
WRITEUNIT();!
!
semSignal (wsem);!
!}!
}!
void main{!
{
!readcount=0; parbegin (reader, writer);!
}!

Leitores e Escritores
Verso 2: prioridade ao escritor

Semforo x para acesso a readcount

Semforo rsem, inibe leitores a acessarem RC se um escritor


estiver acessando

Semforo y para acesso a writecount por parte dos escritores

Semforo z para o controle dos vrios leitores

Um leitor vai para a fila devido a rsem

Leitores adicionais vo para a fila devido a z

Necessrio para que escritor no fique esperando uma fila


longa de leitores devido somente a rsem, caso muitos
leitores apaream

Leitores e Escritores

Leitores e Escritores

Verso 2: prioridade ao escritor

Se o primeiro escritor a acessar, sinaliza


para desabilitar outros leitores

Outros escritores podem


writecount
Excluso mtua para RC
Escritor libera RC

agora

atualiza

Exclusividade para atualizar writecount:


menos um escritor tentando acesso
Se no tiver mais escritor tentando acessar
RC, ento leitores podem acess-lo
Libera acesso ao writecount

Leitores e Escritores

Verso 2: prioridade ao escritor

Se o primeiro escritor a acessar, sinaliza


para desabilitar outros leitores

Outros escritores podem


writecount
Excluso mtua para RC
Escritor libera RC

agora

atualiza

Exclusividade para atualizar writecount:


menos um escritor tentando acesso
Se no tiver mais escritor tentando acessar
RC, ento leitores podem acess-lo
Libera acesso ao writecount

void writer()!
{
!!
while (true){!
semWait (y);!
writecount++;!
if(writecount==1)semWait(rsem);!
semSignal (y);!
semWait (wsem);!
WRITEUNIT();!
semSignal (wsem);!
semWait (y);!
writecount--;!
if(writecount==0)semSignal(rsem);!
semSignal (y);!
}!
}!
void main()!
{!
readcount = writecount = 0;!
parbegin (reader, writer);!
}!

Leitores e Escritores
int readcount, writecount;!
semaphore x=1, y=1, z=1, wsem=1 rsem=1;!
void reader()!
{
!!
while (true){!
semWait (z);!
semWait(rsem);!
semWait (x);!
readcount++;!
if(readcount==1)semWait(wsem);!
semSignal (x);!
semSignal (rsem);!
semSignal(z)!
READUNIT();!
semWait (x);!
readcount--;!
if(readcount==0)semSignal(wsem);!
semSignal (x);!
}!
}!

Verso 2: prioridade ao escritor

Controla nmero de leitores

Se no tiver um escritor, leitor no precisa


estar enfileirado somente

Exclusividade do acesso a readcount

Se um leitor consegue acessar RC, pede


exclusividade: escritor no pode acessar

Libera acesso a readcount (outros leitores


podem acess-lo, mas no o RC)

J que um ganhou acesso a RC, outros


leitores podem ganhar acesso

outra vez, tem que atualizar o readcount,


ento precisa pedir acesso atravs de x

Leitores e Escritores
Troca de mensagens

Controller() simula a rea compartilhada


A verso a seguir d prioridade a escritores
count controla o nmero mximo de leitores, que inicializado por
exemplo, com 100.
count > 0: ento nenhum escritor fez pedido
count = 0: o escritor fez pedido ele ir pedir para finalizar
tambm
Count < 0 escritor espera os leitores acabarem
Tipos de mensagens:
finished, readrequest, writerequest

Leitores e Escritores troca de msg


void reader(int i)!
{!
message rmsg;!
while (true) {!
!rmsg = i;!
!send (readrequest, rmsg);!
!receive (mbox[i], rmsg);!
!READUNIT ();!
!rmsg = i;!
!send (finished, rmsg);!
}!
}!
void writer(int j)!
{!
message rmsg;!
while(true) {!
!rmsg = j;!
!send (writerequest, rmsg);!
!receive (mbox[j], rmsg);!
!WRITEUNIT ();!
!rmsg = j;!
!send (finished, rmsg);!
!}!
}!

void controller()!
{
while (true) {!
!if (count > 0) {!
!
if (!empty (finished)) {!
!
!receive (finished, msg);
!
!
!count++;!
!
} else if (!empty
(writerequest)) {!
!
!receive
(writerequest,
msg);
!
!
!writer_id = msg.id;!
!
!count = count 100;!
!
} else if (!
empty (readrequest)) {!
!
!receive
(readrequest,
msg);
!
!
!count--;!
!
!send (msg.id, "OK");!
!
}!
!}!
!if (count == 0) {!
!
send (writer_id, "OK");!
!
receive (finished, msg);!
!
count = 100;!
!}!
!while (count < 0) {!
!
!receive (finished, msg);
!
!
!count++;!
!}!

Qual o problema com a seguinte implementao


de um escritor e vrios leitores?
int readcount;
!
Semaphore mutex, wrt;

!// inicializada com 0!


!// inicializada com 1!

// Writer : !
// Readers :!
semWait(wrt); !
semWait(mutex);!
/* Writing performed*/ ! readcount := readcount
semSignal(wrt);
if readcount == 1 then
semSignal(mutex);!
/*reading performed*/!
semWait(mutex);!
readcount := readcount
if readcount == 0 then
(wrt);!
semSignal(mutex);!

+ 1;!
semWait(wrt);!

- 1;!
semSignal

Considere o seguinte programa


P1: {!
P2: {!
shared int x;!
shared int x;!
x = 10;!
x = 10;!
while (1) {!
while (1) {!
x = x - 1;!
x = x - 1;!
x = x + 1;!
x = x + 1;!
If (x != 10)!
If (x != 10)!
printf(x=%d",x);!
printf("x=%d",x);!
}!
}!
}!
}!

Suponha que um escalonador de um sistema com um nico


processador, ao implementar
execuo pseudoparalela dos dois
processos concorrentes, intercale as instrues, sem restrio da
ordem da intercalao. Mostre uma sequencia de instrues (trace)
tal que o comando x=10 seja impresso.

Considere o seguinte programa


P1: {!
P2: {!
shared int x;!
shared int x;!
x = 10;!
x = 10;!
while (1) {!
while (1) {!
x = x - 1;!
x = x - 1;!
x = x + 1;!
x = x + 1;!
if (x != 10)!
if (x != 10)!
printf(x=%d",x);!
printf("x=%d",x);!
}!
}!
}!
}!
P1:
P1:
P2:
P1:
P2:
P1:

x = x 1;!
x = x + 1; !
x = x 1;!
if(x != 10)!
x = x + 1; !
printf("x is %d", x);!

9!
10!
9!
9!
10!
10!

Considere o seguinte programa


P1: {!
P2: {!
shared int x;!
shared int x;!
x = 10;!
x = 10;!
while (1) {!
while (1) {!
x = x - 1;!
x = x - 1;!
x = x + 1;!
x = x + 1;!
ff (x != 10)!
if (x != 10)!
printf(x=%d",x);!
printf("x=%d",x);!
}!
}!
}!
}!

Como semforos devem ser adicionados para assegurar que o printf


() no seja executado erroneamente? Sua soluo deve permitir
concorrncia ao mximo.

Considere o seguinte programa


semaphore s;!
P2: {!
parbegin!
shared int x;!
P1: {!
x = 10;!
shared int x;!
for (;;) {!
x = 10;!
semWait (s);!
for (;;) {!
x = x - 1;!
semWait (s);!
x = x + 1;!
x = x - 1;!
if (x != 10)!
x = x + 1;!
printf("x=%d",x);!
if (x != 10)!
semSignal (s);!
printf(x=%d",x);!
}!
semSignal (s);!
}!
}!
}!
parend!