Pasar al contenido principal

Tema 3 - Semáforos

Versión para impresiónSend by email

Los semáforos se crearon para resolver problemas de sincronización, para exclusión mútua y sincronización condicional.

Tienen dos operaciones atómicas:

  • Down: Decrementa el valor del semáforo. Si es cero, la operación se aplaza.
    • Si S>0, S = S-1
    • Si S=0, Se supende la ejecución de la hebra
  • Up: Incrementa el valor del semáforo. Si había alguno esperando le permite seguir.
    • Si hay procesos suspendidos en S, se despierta uno.
    • Si no hay procesos suspendidos en S, S = S+1

 

Exclusión Mútua

Suponiendo una variable compartida M (inicialmente a 0), dos hebras quieren sumar uno a la variable. Se usa un semáforo para que no se produzca ningún error y pueda quedarse la variable con el valor 1 en lugar del valor 2.

Código de las hebras:

int C = 0;
Semaphore Mutex = new Semaphore(1);

-- Código de las hebras:

Mutex.down();
C = C + 1;
Mutex.up();

Creamos una tabla para estudiar el funcionamiento:

Proceso 1
Proceso 2 Mutex C
Inicio Inicio 1 0
Resto a Mutex Me suspendo 0 0
Sumo a C - 0 1
Levanto a P2 Sumo a C 0 2
Fin Sumo a Mutex 1 2
  Fin 1 2

 Otro ejemplo clarificador de su utilidad es el de una hebra productora y otra consumidora:

 

Semaphore Lleno = new Semaphore(0);
Semaphore Vacío = new Semaphore(1);

-- Hebra Productora

Vacio.down();
// Envío de datos al buffer
Lleno.up();

-- Hebra Consumidora

Lleno.down();
// Recibo de datos al buffer
Vacio.up();

 

Productor Consumidor Buffer Lleno Vacio
Inicio Inicio - 0 1
Resto a Vacio Me suspendo - 0 0
Envio a Buffer - Datos 0 0
Levanto a Cons. Recibo del Buffer - 0 0
Fin Sumo a Vacio - 0 1
  Fin - 0 1

 

Puede comprobarse que, se ejecute antes Productor que Consumidor, el resultado es siempre el mismo.