Escolar Documentos
Profissional Documentos
Cultura Documentos
Processos
Semáforos
Semáforos
Mecanismo de sincronização que não requer espera ocupada
Dijkstra propôs usar uma variável inteira para contar o no de
WAKEUPs para uso futuro
Menos complicado
Esta variável, denominada semáforo, pode ter valor 0 (nenhum
WAKEUP pendente) ou um valor inteiro positivo
1
(cont.) Semáforos
P(s) (Down) - checa o valor do semáforo. Se o valor é maior que 0 (zero),
decrementa e continua. Se for igual a 0, o processo é posto para dormir
Ação atômica: é garantido que, uma vez iniciada a operação, nenhum
outro processo tem acesso ao semáforo (essencial para resolver
problemas de sincronização e evitar condições de corrida)
P(s) equivale a:
Se s > 0 então
s := s - 1
senão
bloqueia o processo até s > 0 (= wait(s))
V(s) (Up) - se um ou mais processos estão dormindo no semáforo, um deles é
escolhido aleatoriamente pelo SO e continua sua operação Down (o valor
zero continua). Se não há ninguém “dormindo” no semáforo, incrementa o
valor dele
Operação também é indivisível
V(s) equivale a:
Verifica se existe uma lista com processos bloqueados por causa
de s, se existe
escolhe um e o “acorda”, deixando-o pronto para seguir sua
execução de P(s) (= signal(s))
senão
s := s + 1
Eduardo Nicola F. Zagari 3 Comunicação e Sincronização
Semá
Semáforos como um mecanismo de
sincronizaç
sincronização geral
Semáforo Contador – valor inteiro positivo pode variar sem
limites
Semáforo Binário – valor inteiro só pode variar entre 0 e 1;
Também conhecido como mutex locks
Para fornecer exclusão mútua:
Semaphore S; // initialized to 1
P(S);
criticalSection();
V(S);
2
Deadlock e Starvation
Deadlock – dois ou mais processos ficam esperando
indefinidamente por um evento que pode ser causado apenas
por um dos processos bloqueados
Sejam S e Q dois semáforos inicializados com 1
P0 P1
P(S); P(Q);
P(Q); P(S);
. .
. .
. .
V(S); V(Q);
V(Q); V(S);
Starvation – bloqueio indefinido. Um processo pode nunca ser
removido da fila de semáforos na qual ele está bloqueado.
Problema do Produtor-Consumidor
Dois processos compartilham um buffer de tamanho fixo. Um
dos processos, o produtor, coloca informação no buffer, e o
outro, o consumidor, retira informação do buffer.
Se o buffer estiver cheio, o produtor dorme e é acordado quando
o consumidor remover um item
Se o buffer estiver vazio, o consumidor dorme até que seja
produzido e armazenado algum item
3
Produtor/Consumidor com Semáforos
#define N 100 /* no máximo de ítens */
typedef int semaphore;
semaphore mutex = 1; /* controla acesso à RC */
semaphore empty = N; /* conta slots vazios */
semaphore full = 0; /* conta slots ocupados */
void producer (void) { void consumer(void) {
int item; int item;
while (TRUE) { while (TRUE) {
produce_item(&item); P(&full);
P(&empty); P(&mutex);
P(&mutex); remove_item(&item);
enter_item(item); V(&mutex);
V(&mutex); V(&empty);
V(&full); consume_item(item);
} }
} }
Bounded-Buffer Problem
public class BoundedBuffer implements Buffer
{
private static final int BUFFER SIZE = 5;
private Object[] buffer;
private int in, out;
private Semaphore mutex;
private Semaphore empty;
private Semaphore full;
4
Bounded Buffer Constructor
public BoundedBuffer() {
// buffer is initially empty
in = 0;
out = 0;
buffer = new Object[BUFFER SIZE];
mutex = new Semaphore(1);
empty = new Semaphore(BUFFER SIZE);
full = new Semaphore(0);
}
public void insert(Object item) { /* next slides */ }
5
Bounded Buffer Problem: remove() Method
public Object remove() {
full.acquire();
mutex.acquire();
// remove an item from the buffer
Object item = buffer[out];
out = (out + 1) % BUFFER SIZE;
mutex.release();
empty.release();
return item;
}
6
Bounded Buffer Problem: Consumer
import java.util.Date;
public class Consumer implements Runnable
{
private Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
Date message;
while (true) {
// nap for awhile
SleepUtilities.nap();
// consume an item from the buffer
message = (Date)buffer.remove();
}
}
}
Eduardo Nicola F. Zagari 13 Comunicação e Sincronização