Está en la página 1de 14

TEMA 3.

SEMÁFOROS

1. Introducción
2. Semáforos
3. Uso de los semáforos
3.1. Exclusión Mutua
3.2. Sincronización: Unidireccional y Bidireccional
3.3. Gestión de recursos múltiples
4. Solución para ejemplos típicos con semáforos
4.1. Productor - Consumidor
4.2. Lectores - Escritores
4.3. Filósofos
5. Solución a otros ejemplos
6. Análisis sobre semáforos
Semáforo (I)

q TAD (Dijkstra). Resuelve problemas de concurrencia


§ Estructura
Ø Contador
Ø Cola de procesos
§ Operaciones
Ø Declaración: VAR s: SEMAPHORE;
Ø Initial(s,v) Inicializa el contador con v. s.contador := v;
Ø Wait(s) (definida como P por Dijkstra)
Decrementa en uno el contador si es mayor que cero; Sino,
suspende al proceso en la cola.
PROCEDURE wait(s:SEMAPHORE);
BEGIN (* Operación Atómica *)
IF (s.contador> 0) THEN
s.contador := s.contador -1;
ELSE
suspende_en(S.cola);
END;
Ø Signal(s) (definida como V por Dijkstra)
Incrementa en uno el contador si la cola de procesos está
vacía. Si existe procesos en cola los activa.
PROCEDURE signal(s:SEMAPHORE);
BEGIN (* Operación Atómica *)
IF empty(s.cola) THEN
s.contador := s.contador + 11;
ELSE
activar_desde(S.cola);
END;
Semáforo (II)

q Atomicidad
Ø wait y signal deben realizarse de forma atómica; o sea,
sin que ningún otro proceso utilice el procesador
Ø Solución: Incluir una instrucción de bajo nivel
TEST_AND_SET: comprobar y asignar.

q Tipos
§ Binarios: 0 ó 1
§ Generales: 0 .. N

q Invariantes
§ a) S ³ 0
§ b) S = S0 + #Signal - #Wait

q Usos de los semáforos


§ Exclusión Mutua
§ Sincronización
Ø Unidireccional
Ø Bidireccional
§ Gestión de recursos múltiples
Semaforos: Exclusión Mutua (I)

q Exclusión Mutua: Un solo proceso acceda a un


conjunto de instrucciones (sección_crítica)
PROGRAM principal;
VAR S: SEMAPHORE;
...
PROCESS P1;
...
wait(s);
<sección_crítica>
signal(s);
...
END; (* P1 *)
PROCESS P2;
...
wait(s);
<sección_crítica>
signal(s);
...
END; (* P2 *)
...
BEGIN (* principal *)
initial(s,1);
...
END. (* principal *)
Semaforos: Exclusión Mutua (II)

q Demostración
§ Existe exclusión Mutua

Sea #SC: número de procesos en la sección_crítica


Habrá que demostrar: #SC + S = 1

Examinando el código anterior: #SC = # Wait - #Signal

De la invariante b) S = S0 + #Signal - #Wait


S = S0 - #SC
Como S0=1 S = 1 - #SC
O bien #SC + S = 1 (csqd)

§ No existen interbloqueos

Para que se produzcan interbloqueos debe darse:


S = 0 y #SC = 0
Pero: S + #SC = 0 + 0 = 1 es incosistencia.

§ No se producen esperas indefinidas

Si un proceso P esta suspendido es que S = 0.


Por lo tanto. #SC = 1
Por el código cuando #SC = 0 entonces S = 1 y P entra.
Semaforos: Exclusión Mutua (III)
q Ejemplo: Dos procesos incrementan en 10 la variable X compartida.
PROGRAM excmutua;
VAR semaforo : semaphore ; (* Definición del Semaforo *)
X: INTEGER;

PROCESS P1;
VAR i: INTEGER;
BEGIN
FOR i:=1 TO 10 DO
BEGIN
WAIT(semaforo);
X:= X+1;
SIGNAL(semaforo)
END
END; (* P1 *)

PROCESS P2;
VAR i:INTEGER;
BEGIN
FOR i:=1 TO 10 DO
BEGIN
WAIT(semaforo);
X:= X + 1;
SIGNAL(semaforo)
END
END; (* P2 *)

BEGIN (* Principal *)
INITIAL(semaforo,1);
COBEGIN
p1; p2
COEND
END. (* excmutua*)
Semáforos: Sincronización

q Sincronización: capacidad de que un proceso informe a otro sobre


su estado de ejecución, generalmente, para que el otro progrese.
q Puede ser de dos tipos:
§ Unidireccional: Un proceso sincroniza con otro.

§ Bidireccional: Ambos procesos sincronizan


Semaforos: Gestión de recursos múltiples

q Recursos Múltiples: Existe varios ejemplares del mismo recurso.


q Gestión con Semáforos. Contador General
PROGRAM principal;
CONST N= ? (* Número de procesos *)
R= ? (* Número de recursos *)
VAR S: SEMAPHORE; (* Semáforo General *)
...
PROCESS TYPE TP;
...
wait(s);
<uso_del_recurso>
signal(s);
...
END; (* TP *)
VAR p: array [1..N] of TP;
...
BEGIN (* principal *)
initial(s,R); (* Inicializado Nº de recursos *)
...
END. (* principal *)
q Ejemplo. Garaje de vehículos
20 coches (procesos)
Tpo circulando, Tpo estacionados
Aparcamiento 15 plazas
Semáforos: Productor-Consumidor (I)

q Productor-Consumidor buffer ilimitado


PROGRAM ProdConsInf;
VAR
elto: semaphore; (* General *)
s: semaphore; (* Binario *)

PROCESS productor;
BEGIN
REPEAT
producir;
wait(s); (* acceso exclusivo al buffer *)
dejar_en_buffer;
signal(s);
signal(elto); (* elemento en buffer *)
FOREVER
END; (* Productor *)

PROCESS consumidor;
BEGIN
REPEAT
wait(elto); (* Esperar elemento *)
wait(s); (* acceso exclusivo al buffer *) BEGIN (* PRINCIPAL *)
coger_del_buffer; initial(s,1);
signal(s); (* Fin de exclusión mutua *) initial(elto,0);
consumir; COBEGIN
FOREVER productor;
END; (* Consumidor *) consumidor
COEND;
END. (* PRINCIPAL *)
Semáforos: Productor-Consumidor (II)
q Productor-Consumidor buffer limitado (array)

PROGRAM ProdConsFin;
CONS
MAX = ... ; (* Cap. Buffer *)
TYPE
dato : ... ; (* Tipo de datos *)
VAR PROCESS consumidores;
buffer : array [1..MAX] of dato; VAR cdato : dato;
producir, consumir: semaphore; BEGIN
ps, cs: semaphore; REPEAT
ent, sal: integer; wait(consumir);
wait(cs);
PROCESS productores; cdato:= buffer[sal];
VAR pdato : dato; sal := (sal mod MAX) + 1;
BEGIN signal(cs);
REPEAT signal(producir);
wait(producir); consumir(cdato);
pdato := producir(); FOREVER
wait(ps); END; (* Consumidores *)
buffer[ent]:= pdato;
ent := (ent mod MAX) + 1; BEGIN (* PRINCIPAL *)
signal(ps); initial(ps,1);
signal(consumir); initial(cs,1);
FOREVER initial(consumir,0);
END; (* Productores *) initial(poducir,MAX);
ent:=1; sal:=1;
COBEGIN
productores;
consumidores
COEND;
END. (* PRINCIPAL *)
Semáforos: Lectores-Escritores

PROGRAM LectEscr;
VAR
nlect : integer;
s,escribir : semaphore;

PROCESS Lectores;
BEGIN
REPEAT
wait(s); (* Acceso exclusivo a variable *)
nlect := nlect + 1;
IF nlect = 1 THEN wait(escribir); (* Primer lector impide escritura *)
signal(s);
LEER;
wait(s); (* Acceso exclusivo a variable *)
nlect := nlect - 1;
IF nlect = 0 THEN signal(escribir); (* Último lector habilita escritura *)
signal(s);
FOREVER
END; (* Lectores *)

PROCESS Escritores;
BEGIN
REPEAT
wait(escribir); (* Espera escribir *) BEGIN (* PRINCIPAL *)
ESCRIBIR; nlect := 0;
signal(escribir); (* Permitir escribir *) initial(s,1);
FOREVER initial(escribir,1);
END; (* Escritores *) COBEGIN
lectores;
escritores
COEND
END. (* PRINCIPAL *)
Semáforos: Filósofos (I)

PROGRAM FilosofSem1;

CONST
N = 5;

VAR
palillo : array [1..N] of semaphore; (* Semáforo binario por palillo *)
i : integer;

PROCESS filosofos(num : integer);


BEGIN
REPEAT
PENSANDO;
wait(palillo[num]); (* Pedir palillo *)
wait(palillo[(num mod N) + 1]); (* Pedir otro palillo *)
COMIENDO;
signal(palillo[num]); (* Dejar palillo *)
signal(palillo[(num mod N) + 1]); (* Dejar el otro palillo *)
FOREVER
END; (* Filosofos *)
BEGIN (* PRINCIPAL *)
FOR i := 1 TO N DO
initial(palillo[i],1); (* palillos sin usar *)
COBEGIN
FOR i := 1 TO N DO
filosofos(i);
COEND
END.
Semáforos: Filósofos (II)

PROGRAM FilosofSem2;
CONST
N = 5;
VAR
palillo : array [1..N] of semaphore; (* Semáforo binario por palillo *)
mesa : semaphore; (* Semáforo General para mesa *)
i : integer;

PROCESS filosofos(num : integer);


BEGIN
REPEAT
PENSANDO;
wait(mesa); (* Espera mesa libre *)
wait(palillo[num]); (* Esperar palillo *)
wait(palillo[(num mod N) + 1]); (* Esperar otro palillo *)
COMIENDO;
signal(palillo[num]); (* Dejar palillo *)
signal(palillo[(num mod N) + 1]); (* Dejar otro palillo *)
signal(mesa) (* Dejar mesa libre *)
FOREVER
END; (* Filosofos *)

BEGIN (* PRINCIPAL *)
FOR i := 1 TO N DO
initial(palillo[I],1);
initial(mesa,N - 1); (* En la mesa pueden comer n-1 filosofos a la vez.*)
COBEGIN
FOR i := 1 TO N DO
filosofos(I);
COEND
END.
Semáforos: Análisis.

q Ventajas
§ Simples
§ Eficientes
§ Poderosos
q Problemas
§ No estructurados. El uso depende del programador
Omitir un wait Þ Falta de Exclusión
Omitir un Signal Þ Interbloqueo

§ No están relacionados con el recurso que protegen


§ No especifica las operaciones que se deben hacer con
el recurso.

También podría gustarte