ejemplos para tener en cuenta
TRANSCRIPT
Tema 4.- RCC, Monitores y Recursos
ü 4.1.- Introducción
ü 4.2.- Regiones Críticas y Regiones CríticasCondicionales
ü 4.3.- Monitores
ü 4.4.- Recursos
Introducción
1SemáforosØ No estructurados. El uso depende del programador
Ø No están relacionados con el recurso que protegen
Ø No especifica las operaciones que se deben hacer conel recurso.
1ProblemasØ Facilidad de error por parte del programador
Ø Dificultad para descubrir el objetivo del semáforopor la ausencia de significado semántico
Ø Posibilidad de uso incorrecto del recurso por parte delos procesos
1Otros Constructores para concurrencia:Para solucionar, en la medida de lo posible, estos problemas.
Ø Regiones Críticas (RC) y
Regiones Críticas Condicionales (RCC)
Ø Monitores
Ø Recursos o unidades protegidas
Región Crítica (I)
1Definición (Brinch Hansen, 1972)Ø Una RC es un constructor que resuelve el problema
de Exclusión Mutua estableciendo un mecanismo deacceso a estos recursos.
Ø Cada recurso debe ser definido como compartido (shared).
Ø Existirá una región para cada recurso.
Ø No está permitido el acceso al recurso fuera de la región.
Ø Cada región tiene asociada una cola de procesos.
NOTA: No implementado en PASCAL FC
1DeclaraciónVAR <var-compartida> : SHARED <tipo> ;
1ConstructorREGION <var-compartida> DO
<Sección_crítica> ;
Región Crítica (II)
1Ejemplo: Dos procesos que acceden a una sección crítica
PROGRAM RegionCritica;
VAR v : SHARED INTEGER;
PROCESS P1;
...
REGION v DO
<Sección_crítica> ;
...
END;
PROCESS P2;
...
REGION v DO
<Sección_crítica> ;
...
END;
1MejorasØ Estructura el acceso a la sección crítica
Ø Establece significado al constructor
1ProblemasØ Sincronización
Regiones Críticas Condicionales (I)
1Sincronización con RC...
REPEAT
REGION v DO
BEGIN
ok := (v > 0) ;
IF ok THEN
v := v - 1;
END;
UNTIL ok;
...
Problema: Espera activa por lo tanto no es una buena solución
1Regiones Crítica Condicionales (RCC)Ø La misma idea que las RC
Ø Establecen una guarda (condición) a satisfacer para accedera la Región
Ø La región tiene asociada una cola con la guarda.
1ConstructorREGION <var-compartida> WHEN <guarda> DO
<Sección_crítica> ;
Regiones Críticas Condicionales (II)
1Solución a ejemplos típicos
ØProductores - Consumidores
ØFilósofos
1Ejemplo: Pasar el puenteCruzar a 20 personas, 10 mayores y 10 niños, (procesos) unpuente colgante que tiene como limitación que no permite elpaso simultaneo de más de 4 personas pequeñas o de 2pequeñas y una mayor.
RCC: Problema Productor-Consumidor (III)PROGRAM ProdCons;CONST MAX=...;TYPE
TDato = ... ;TBuffer = RECORD
sigent, sigsal, cont: INTEGER;eltos: ARRAY [1..MAX] OF TDato;
END;VAR buffer : SHARED TBuffer;
PROCESS Productor;VAR pdato: TDato;BEGIN
...pdato:=producir();REGION buffer WHEN buffer.cont<MAX DO
BEGINbuffer.elto[buffer.sigent ] := pdato;buffer.sigent := (buffer.sigent MOD MAX) + 1;buffer.cont := buffer.cont + 1;
END;...
END;PROCESS Consumidor;VAR cdato: TDato;BEGIN
...REGION buffer WHEN buffer.cont<>0 DO
BEGINcdato := buffer.elto[buffer.sigsal];buffer.sigsal := (buffer.sigsal MOD MAX) + 1;buffer.cont := buffer.cont - 1;
END;...
END;BEGIN (* Principal *)
REGION buffer WHEN true DObuffer.sigent:=1; buffer.sigsal:=1; buffer.cont := 0;
END;COBEGIN
Productores; Consumidores;COEND
END.
RCC: Problema Filósofos (IV)PROGRAM Filosofos;
CONST NFILO = 5;
VAR
PalillosDisp : SHARED ARRAY [1..NFILO ] OF INTEGER;
i: INTEGER;
PROCESS TYPE filosofos(n. INTEGER);
BEGIN
REPEAT
(* PENSANDO *)
REGION PalillosDisp WHEN PalillosDisp[n ]=2 DO
BEGIN
PalillosDisp[ (n MOD NFILO) + 1 ] :=
PalillosDisp [ (n MOD NFILO) + 1 ] - 1;
PalillosDisp[ ((n+NFILO-2) MOD NFILO) + 1 ] :=
PalillosDisp [ ((n+NFILO-2) MOD NFILO) + 1 ] - 1;
END;
(* COMIENDO *)
REGION PalillosDisp WHEN true DO
BEGIN
PalillosDisp[ (n MOD NFILO) + 1 ] :=
PalillosDisp [ (n MOD NFILO) + 1 ] + 1;
PalillosDisp[ ((n+NFILO-2) MOD NFILO) + 1 ] :=
PalillosDisp [ ((n+NFILO-2) MOD NFILO) + 1 ] + 1;
END;
FOREVER
END;
VAR filo: ARRAY [1..NFILO ] OF Filosofos;
BEGIN (* Principal *)
REGION PalillosDisp WHEN true DO
FOR i:= 1 TO NFILO DO
PalillosDisp := 2;
COBEGIN
FOR i:=1 To NFILO DO filo[i ](i);
COEND
END.
PROGRAM PuenteColgante;VAR puente: SHARED RECORD
npp :INTEGER;npg: INTEGER;
END;i : INTEGER;
PROCESS TYPE PersonasPequeñas(i: INTEGER);BEGIN
...REGION puente WHEN (npg=0 and npp<4) or (npg=1 and npp<2) DO
npp := npp + 1;(*Pasando el Puente*)REGION puente WHEN true DO
npp := npp - 1;...
END;VAR pp: ARRAY [1..10] OF PersonasPequeñas;:PROCESS TYPE PersonasMayores;BEGIN
...REGION puente WHEN (npg=0 and npp<=2) DO
npg := npg + 1;(* Pasando el puente *)REGION puente WHEN true DO
npg := npg - 1;...
END;VAR pg: ARRAY [1..10] OF Personasmayores;BEGIN (* Principal *)
REGION puente WHEN true DOBEGIN
npp:= 0; npg:= 0END;
COBEGINFOR i:=1 TO 10 DO
BEGINpp[i] (i); pg[i](i)
END;COEND;
END.
RCC: Problema Puente Colgante (V)
RC y RCC: Análisis (VI)
1SolucionanØ Establece una estructura para la exclusión mutua y
sincronización.
Ø Asigna significado semántico a la estructura
1ProblemasØ No define las operaciones a realizar sobre el recurso.
Ø La protección puede realizarse en cualquier parte delprograma.
Ø El anidamiento de RCC puede ser muy problemático
REGION x DO REGION y DO
REGION y DO REGION x DO
x := y; x := y;
Monitores (I)
1DefiniciónEs constructor o entidad pasiva externa, similar a un modulo o paquete,que establece acceso exclusivo a su código, a la vez que abstracción dedatos.
Está compuesto por un conjunto de atributos privados (datos críticos) yun conjunto de procedimientos o funciones unos públicos (accesiblesdesde los procesos) y otros privados únicamente utilizables desdedentro del propio monitor.
1Sintaxis. (En la zona de declaración de un programa).
MONITOR <NombreMonitor> ;EXPORT <ListaProcedimientosPúblicos>;(* Zona de Declaración *)
CONST / TYPE / VAR / PROCEDURES / FUNCTIONS(* Cuerpo Opcional *)BEGIN
(* Cuerpo generalmente para inicializar variables *)END;
1Uso desde procesos<NombreMonitor>.<ProcedimientoPúblico> ;
Monitores (II)
1FuncionamientoØ El cuerpo del monitor se ejecuta al iniciar el programa
Ø Cuando un proceso realiza una llamada a un procedimiento seejecuta ese procedimiento impidiendo que cualquier otroproceso utilice el monitor
Ø Cualquier otro proceso que desee utilizar un monitor en usopor otro proceso queda suspendido en una cola de procesos enespera propia del monitor.
Ø Cuando un proceso finaliza el uso de un monitor se analiza lacola de procesos en espera de ese monitor permitiendo elacceso a alguno que estuviese esperando.
1EjemplosMONITOR Ejemplo1;EXPORT Increm, Decrem, Valor;VAR dato;
Procedure Increm (Cant : INTEGER);BEGIN
Dato := Dato + Cant;END;
Procedure Decrem (Cant : INTEGER);BEGIN
Dato := Dato - Cant;END;
Function Valor (Cant: INTEGER): INTEGER;BEGIN
Valor := Dato;END;
BEGINDato := 0;
END;
1Ejemplo.(Dos procesos incrementan en 10 una variable).
program Ejemplo;
const
nprocs =2;
var
j: integer;
monitor contador; (* se define el monitor *)
export (* define los procedimientos a exportar *)
inc, escribe;
var (* variables locales al monitor *)
X: integer;
procedure inc;
begin
X := X + 1
end; (* inc *)
procedure escribe;
begin
writeln(’X = ',X:2)
end; (* escribe *)
begin (* cuerpo del monitor *)
nolineas := 0
end; (* monitor contador *)
Monitores (III)
process type Pi;var
i: integer;begin
for i := 1 to 20 docontador.inc
end; (* Pi *)
varp: array[1..nprocs] of Pi;
begincobegin
for j := 1 to nprocs doproceso[j]
coend;contador.escribe
end.
Monitores (IV)
1Sincronización con MonitoresØUso de condiciones (CONDITION)
1DefiniciónVAR <nomb_var>: Condition;
<nomb_var>: ARRAY[1..MAX of CONDITION
1OperacionesDelay(c): Bloquea al proceso que la ejecute en una colade procesos asociada a la condición c.
Resume(c): Despierta al primer proceso bloqueado en lacondición c.
Empty(c): función que devuelve TRUE se la colaasociada a c está vacía.
1Implementación de ResumeØ Última sentencia
Obligar que sea la última sentencia antes de abandonar el monitor
Ø Reactivación retardadaCuando un proceso ejecuta un resume, envía al primer proceso dela cola a una segunda cola. El proceso que ejecutó resumecontinua y al abandonar el monitor se chequea la segunda coladando paso al primer proceso bloqueado en ella.
Ø Suspensión del proceso activoCuando un proceso ejecuta un resume, éste es bloqueado en unasegunda cola interna, dejando paso al primer proceso en la colade monitor. Cuando se ejecuta una nueva operación resume o unproceso abandona el monitor se evalúa esta cola interna dandopaso al primer proceso bloqueado en ella.
Monitores (V)
1Productor-ConsumidorPROGRAM PCMonitor;
MONITOR Buffer;
EXPORT Poner, Coger;
CONST MAX = 4;
VAR
Almacen: ARRAY[0..MAX] OF CHAR;
cont: INTEGER;
NoLleno, NoVacio: CONDITION;
sigent, sigsal: INTEGER;
PROCEDURE Poner(c: CHAR);
BEGIN
IF cont > MAX THEN delay(NoLleno);
Almacen[sigent] := c;
cont := cont + 1;
sigent:= (sigent+ 1) mod (MAX + 1);
resume(NoVacio)
END; (* Poner *)
PROCEDURE Coger(var c: CHAR);
BEGIN
IF cont = 0 THEN delay(NoVacio);
c := Almacen[sigsal];
cont := cont - 1;
sigsal := (sigsal + 1) mod (MAX + 1);
resume(NoLleno)
END; (* Coger *)
BEGIN (* Cuerpo*)
cont := 0;
sigent := 0;
sigsal := 0
END; (* Monitor buffer*)
PROCESS Productor;VAR
Pdato: char;BEGIN
FOR Pdato := 'a' TO 'z' DOBuffer.Poner(Pdato);
END; (* PRODUCTOR *)
PROCESS Consumidor;VAR
Cdato: char;BEGIN
REPEATBuffer.Coger(Cdato);write(Cdato)
UNTIL Cdato = 'z';writeln
END; (* CONSUMIDOR *)
BEGIN (* main *)COBEGIN
PRODUCTOR;CONSUMIDOR
COENDEND.
Monitores (VI)
1FilósofosPROGRAM FilosofoMon;
CONST NF = 5;
VAR j : INTEGER;
MONITOR Palillos;
EXPORT Coger, Dejar;
VAR palillos: ARRAY[1..NF] OF INTEGER;
comer: ARRAY [1..NF] OF CONDITION;
k: INTEGER
PROCEDURE Coger(i: INTEGER);
BEGIN
IF palillos[i]<>2 THEN delay(comer[i]);
PalillosDisp[ (n MOD NF) + 1 ] := PalillosDisp [ (n MOD NF) + 1 ] - 1;
PalillosDisp[ ((n+NF-2) MOD NF) + 1 ] := PalillosDisp [ ((n+NF-2) MOD NF) + 1 ]-1
END;
PROCEDURE Dejar(i:INTEGER);
BEGIN
PalillosDisp[ (n MOD NF) + 1 ] := PalillosDisp [ (n MOD NF) + 1 ] + 1;
PalillosDisp[ ((n+NFILO-2) MOD NF) + 1 ] := PalillosDisp [ ((n+NF-2) MOD NF) + 1 ] +1;
IF palillos[(n MOD NF) + 1] = 2 THEN resume(comer[(n MOD NF) + 1]);
IF palillos[((n+NF-2) MOD NF) + 1] = 2 THEN resume(comer[((n+NF-2) MOD NF) + 1]);
END;
BEGIN
FOR k:=1 TO NF DO Palillos[k] := 2;
END;
PROCESS TYPE Filosofos(n:INTEGER);
BEGIN
(* PENSANDO *)
Palillos.Coger(i);
(* COMIENDO *)
Palillos.Dejar(i);
END;
VAR filo : ARRAY[1..NF] OF Filosofos;
BEGIN
COBEGINFOR j:=1 TO NF DO
filo[j](j);COEND
END.
Monitores (VII)Lectores - Escritores
PROGRAM LEMon;
MONITOR LectEscr:
EXPORT Entrar, Salir;
VAR NLect: INTEGER; Escribiendo: BOOLEAN; Leer, Escribir: CONDITION;
PROCEDURE Entrar(Lector : BOOLEAN);
BEGIN
IF Lector THEN BEGIN
IF Escribiendo OR NOT EMPTY(Escribir) THEN delay(leer);
Nlect := Nlect + 1;
resume(leer);
END
ELSE BEGIN
IF Escribiendo OR (Nlect<>0) THEN delay(Escribir);
Escribiendo:=TRUE;
END;
END;
PROCEDURE Salir(Lector : BOOLEAN);
BEGIN
IF Lector THEN
BEGIN
Nlect:=Nlect – 1;
IF Nlect=0 THEN resume(escribir);
END
ELSE
BEGIN
Escribiendo:=FALSE;
IF NOT EMPTY(leer) THEN resume(leer)
ELSE resume(Escribir);
END;
END;
BEGIN
Escribiendo := FALSE;
NLECT:=0;
END;
PROCESS Lectores;BEGIN...
LectEsc.Entrar(TRUE);LEERLectEsc.Salir(TRUE);
.....END;
PROCESS ESCRITORES;BEGIN.....
LectEsc.Entrar(FALSE);ESCRIBIR;LectEsc.Salir(FALSE);
.....END;
Monitores (VIII)
Ø Reloj – Alarma (I)
program ALARMCLOCK;const PMAX = 3;
monitor ALARM;Export WAKEUP, TICK;var NOW: integer; WAKE: condition;
procedure WAKEUP(N, ALARMCALL: integer);beginwhile NOW < ALARMCALL dobegindelay(WAKE);resume(WAKE);end
end; (* WAKEUP *)
procedure TICK;beginNOW := NOW + 1;IF NOW=24 THEN then NOW=0;resume(WAKE)
end; (* TICK *)
begin (* body *)NOW := 0
end; (* ALARM *)
monitor SCREEN;export PRINT;procedure PRINT(N: integer);beginwriteln('Process ',N:1,' aWAKEs')
end; (* PRINT *)end; (* SCREEN *)
Monitores (VIII)
Ø Reloj – Alarma (II)
process Reloj;(* provides the clock "ticks" *)beginrepeatsleep(1);ALARM.TICK
foreverend; (* Reloj *)
process type CLIENTTYPE(N: integer);VAR ALARMCALL:Intenger;beginrepeatALARMCALL:=RANDOM(24);ALARM.WAKEUP(n, ALARMCALL);SCREEN.PRINT(N)
foreverend; (* CLIENTTYPE *)
varDormilones: array[1..PMAX] of CLIENTTYPE;PLOOP: integer;
begincobeginRELOJ;for PLOOP := 1 to PMAX doDORMILONES[PLOOP](PLOOP)
coendend.
Monitores (IX)
Ø Simulación de Semáforos con Monitores (Implementación)
program SEMMON;
(* Simulacion de un semáforo binario con un monitor *)
var SHARED: integer;
monitor SEM;export WAIT, SIGNAL;
var VALUE: integer;NOTZERO: condition;
procedure WAIT;beginif VALUE = 0 thendelay(NOTZERO);
VALUE := 0end; (* WAIT *)
procedure SIGNAL;beginVALUE := 1;resume(NOTZERO)
end; (* SIGNAL *)
begin (* body *)VALUE := 1
end; (* SEM *)
Monitores (X)
Ø Simulación de Semáforos con Monitores (Uso)
program SEMMON;(* Simulacion de un semáforo binario con un monitor *)
var SHARED: integer;
monitor SEM;.... (* Monitor anterior *)end; (* SEM *)
process type INC;var LOOP: integer;beginfor LOOP := 1 to 20 dobeginSEM.WAIT;SHARED := SHARED + 1;SEM.SIGNALend
end; (* INC *)
varINC1,INC2: INC;
beginSHARED := 0;cobeginINC1;INC2
coend;writeln('Total admitted: ',SHARED:1)
end.
Monitores (XI)
1Análisis de MonitoresØ Desventajas
Ø Mecanismo de sincronización a voluntad delprogramador
Recursos (I)
1Definición: Monitores + RCCØ Funde la semántica de Monitores y RCC
aprovechando las ventajas de ellas
1Sintaxis. (En la zona de declaración de un programa).
RESOURCE <NombreRecurso> ;EXPORT <ListaProcedimientosPúblicos>;(* Zona de Declaración *)
CONST / TYPE / VAR / PROCEDURES / FUNCTIONSPROCEDIMIENTOS CON GUARDAS
(* Cuerpo Opcional *)BEGIN
(* Cuerpo generalmente para inicializar variables *)END;
1Procedimientos con GuardasGUARDED PROCEDURE <nombre> WHEN <cond>;
(* Zona de Declaración Local*)
BEGIN
(* Cuerpo *)
END;
1Llamada a un procedimiento públiconom_recurso. nomb_proc(list_para);
Recursos (II)
1Funcionamiento1. Un proceso que intenta entrar en un recurso que en ese momento está
ocupado, se "suspende" en la cola del recurso.
2. Un proceso que llama a un procedimiento cuya guarda se evalúa afalse se pone en estado "suspendido" en la cola de ese procedimiento.
3. Un proceso suspendido en la cola de un procedimiento pasará aejecutable cuando un proceso deje el recurso y la guarda tome elvalor de true.
4. Un proceso suspendido en la cola de un recurso pasará a ejecutablecuando un proceso deje el recurso y no haya procesos suspendidos enun procedimiento con guarda del recurso, cuya guarda toma el valorde true.
1Facilidad REQUEUELa instrucción REQUEUE se utiliza para abandonar el procedimiento conguarda actual y transferir la llamada a otro, dentro del mismo recurso odentro de otro. Su sintaxis es:
requeue [nomb_recurso.]nom_procedure(lis-para)
Recursos (III)
1Productor - ConsumidorPROGRAM PCMonitor;
RESOURCE Buffer;
EXPORT
Poner, Coger;
CONST
MAX = 5;
VAR
Almacen: ARRAY[0..MAX-1] OF CHAR;
cont: INTEGER;
sigent, sigsal: INTEGER;
Guarded Procedure Poner(c: CHAR) WHEN cont<MAX;
BEGIN
Almacen[sigent] := c;
cont := cont + 1;
sigent:= (sigent+ 1) mod (MAX + 1);
END; (* Poner *)
Guarded procedure Coger(var c: CHAR) when cont <>0;
BEGIN
c := Almacen[sigsal];
cont := cont - 1;
sigsal := (sigsal + 1) mod (MAX + 1);
END; (* Coger *)
BEGIN (* Cuerpo*)
cont := 0;
sigent := 0;
sigsal := 0
END; (* Recurso buffer*)
PROCESS Productor;VAR Pdato: char;BEGIN
FOR Pdato := 'a' TO 'z' DOBuffer.Poner(Pdato);
END; (* PRODUCTOR *)
PROCESS Consumidor;VAR Cdato: char;BEGIN
REPEATBuffer.Coger(Cdato);write(Cdato)
UNTIL Cdato = 'z';writeln
END; (* CONSUMIDOR *)
BEGIN (* main *)COBEGIN
PRODUCTOR;CONSUMIDOR
COENDEND.
Recursos (IV)
1 Reloj-Alarma (I)PROGRAM ALARMCLOCK;
const PMAX = 3;
resource ALARM;
export SLUMBER, TICK;
var NOW: integer;
queue : integer; freed1, freed2 : boolean;
guarded procedure SLUMBER2(AL: integer) when freed2; forward;
guarded procedure SLUMBER1(AL: integer) when freed1;
begin
if NOW < AL then requeue SLUMBER2(AL)
end; (* SLUMBER *)
guarded procedure SLUMBER2;
begin
if NOW < AL then
requeue SLUMBER1(AL)
end; (* SLUMBER *)
guarded procedure SLUMBER(ALARMACALL: integer) when true;
begin
if NOW < ALARMCALL then
if queue = 1 then requeue SLUMBER1(ALARMCALL)
else requeue SLUMBER2(ALARMCALL)
end; (* SLUMBER *)
procedure TICK;
begin
NOW := NOW + 1;
if queue = 1 then
begin
queue := 2; freed1 := true; freed2 := false
end else
begin
queue := 1; freed1 := false; freed2 := true
end
end; (* TICK *)
Recursos (V)
1 Reloj-Alarma (II)begin (* body *)
NOW := 0;
queue := 1;
freed1 := false
end; (* ALARM *)
resource SCREEN;
export
PRINT;
procedure PRINT(N: integer);
begin
writeln('Process ',N:1,' awakes')
end; (* PRINT *)
end; (* SCREEN *)
process DRIVER;
begin
repeat
sleep(1);
ALARM.TICK
forever
end; (* DRIVER *)
process type SLEEPERTYPE(N: integer);
VAR llamar:INTEGER;
begin
repeat
alarma=ramdon(24);
ALARM.SLUMBER(alarma);
SCREEN.PRINT(N)
(* get up and go to work *)
forever
end; (* SLEEPERTYPE *)
varSLEEPERS: array[1..PMAX] of
SLEEPERTYPE;PLOOP: integer;
begincobeginDRIVER;for PLOOP := 1 to PMAX doSLEEPERS[PLOOP](PLOOP)
coendend.
Recursos (VI)
Ø Filósofos (I)
program philres1;(* Dining Philosophers - resource version *)var j, num: integer;
resource forkcontrol;export getforks, putforks;var forks: array [0..4] of integer;i: integer; barrier1: boolean;
guarded procedure waiting1(i: integer) when not barrier1; forward;guarded procedure waiting2(i: integer) when barrier1; forward;
guarded procedure getforks(i: integer) when true;beginif forks[i] <> 2 then
if barrier1 then requeue waiting1(i)else requeue waiting2(i);
forks[(i+1) mod 5] := forks[(i+1) mod 5] - 1;forks[(i+4) mod 5] := forks[(i+4) mod 5] - 1;writeln('Philosopher ',i,' eats')end; (* getforks *)
procedure putforks(i: integer);beginwriteln('Philosopher ',i,' finishes');forks[(i+1) mod 5] := forks[(i+1) mod 5] + 1;forks[(i+4) mod 5] := forks[(i+4) mod 5] + 1;barrier1 := not barrier1end; (* putforks *)
Recursos (VII)
Ø Filósofos (II)
(continuación)
guarded procedure waiting1;beginrequeue getforks(i)
end;
guarded procedure waiting2;beginrequeue getforks(i)
end;
begin (* resource body *)barrier1 := true;for i := 0 to 4 doforks[i] := 2
end; (* forkcontrol *)
process type philtype(n: integer);
beginrepeatsleep(random(5)); (* THINKING *)forkcontrol.getforks(n);sleep(random(5)); (* EATING *)forkcontrol.putforks(n)
foreverend; (* philosopher *)
varphilosopher: array[0..4] of philtype;
begin (* main *)cobeginfor num := 0 to 4 dophilosopher[num](num)
coendend.
Recursos (VIII)
Ø Simulación de un Semáforo binario
resource BINSEM;
export
WAIT, SIGNAL;
var
VALUE: integer;
guarded procedure WAIT when VALUE > 0;
begin
VALUE := VALUE - 1
end; (* WAIT *)
procedure SIGNAL;
begin
VALUE := VALUE + 1
end; (* SIGNAL *)
begin (* body *)
VALUE := 1
end; (* BINSEM *)
Recursos (IX)
Ø Uso del Semáforo binario anterior
program SEMRES;(* simulation of binary semaphore by resources *)
var COUNT: integer;
resource BINSEM;.... (* Recurso anterior *)end; (* BINSEM *)
process type INC;var I: integer;beginfor I := 1 to 20 dobeginBINSEM.WAIT;COUNT := COUNT + 1;BINSEM.SIGNALend
end; (* INC *)
var TURNSTILE1, TURNSTILE2: INC;
beginCOUNT := 0;cobeginTURNSTILE1;TURNSTILE2
coend;writeln('Final total; ',COUNT:1)
end.