Você está na página 1de 7

Sistemas Operacionais

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

 Apenas duas operações são definidas sobre estas variáveis: as


operações P (Down) e V (Up)

Eduardo Nicola F. Zagari 2 Comunicação e Sincronização

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

Eduardo Nicola F. Zagari 4 Comunicação e Sincronização

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.

Eduardo Nicola F. Zagari 5 Comunicação e Sincronização

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

Eduardo Nicola F. Zagari 6 Comunicação e Sincronização

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

Eduardo Nicola F. Zagari 7 Comunicação e Sincronização

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;

// Continued on next Slide

Eduardo Nicola F. Zagari 8 Comunicação e Sincronização

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 */ }

public Object remove() { /* next slides */ }


}

Eduardo Nicola F. Zagari 9 Comunicação e Sincronização

Bounded Buffer Problem: insert() Method


public void insert(Object item) {
empty.acquire();
mutex.acquire();
// add an item to the buffer
buffer[in] = item;
in = (in + 1) % BUFFER SIZE;
mutex.release();
full.release();
}

Eduardo Nicola F. Zagari 10 Comunicação e Sincronização

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;
}

Eduardo Nicola F. Zagari 11 Comunicação e Sincronização

Bounded Buffer Problem: Producer


import java.util.Date;
public class Producer implements Runnable
{
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
Date message;
while (true) {
// nap for awhile
SleepUtilities.nap();
// produce an item & enter it into the buffer
message = new Date();
buffer.insert(message);
}
}
}
Eduardo Nicola F. Zagari 12 Comunicação e Sincronização

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

Bounded Buffer Problem: Factory


public class Factory
{
public static void main(String args[]) {
Buffer buffer = new BoundedBuffer();
// now create the producer and consumer threads
Thread producer = new Thread(new Producer(buffer));
Thread consumer = new Thread(new Consumer(buffer));
producer.start();
consumer.start();
}
}

Eduardo Nicola F. Zagari 14 Comunicação e Sincronização

Você também pode gostar