1
Sistemas Operativos Tema 7. Concurrencia
1
© 1998-2012 José Miguel Santos – Alexis Quesada – Francisco Santana
Contenidos
n Sistemas concurrentes n El problema de la sección crítica n Semáforos n Monitores
2
Bibliografía
n Fundamentos de Sistemas Operativos q S. Candela, C.R. García, A. Quesada, F.J. Santana, J.M. Santos.
Thomson, 2007 q Capítulo 3
n Programación Concurrente q J.T. Palma, M.C. Garrido, F. Sánchez, A. Quesada q Capítulos 1, 2, 3, 4, 5 y 6
n Principles of Concurrent and Distributed Programming q M. Ben-Ari. Prentice Hall, 1990
n Concurrent Programming q A. Burns, G. Davies. Addison-Wesley, 1993 q Capítulo 7
3
Contenidos
n Sistemas concurrentes n El problema de la sección crítica n Semáforos n Monitores
4
Modelo del sistema
n Conjunto de procesos cooperativos q Red de cajeros automáticos q Sistema de reserva de billetes q Servidor de impresión q ...
5
¿Qué es concurrencia?
n Definición de diccionario: coincidir en el espacio o en el tiempo dos o más personas o cosas.
n En Informática, se habla de concurrencia cuando hay una existencia simultánea de varios procesos en ejecución.
n Ojo, concurrencia existencia simultánea no implica ejecución simultánea.
6
2
Paralelismo y concurrencia
n El paralelismo es un caso particular de la concurrencia.
n Se habla de paralelismo cuando ocurre la ejecución simultánea de instrucciones.
7
Procesos cooperativos
n Necesidades de sincronización y comunicación
n Los procesos concurrentes tendrán necesidad de comunicarse información
n Además, será necesario en ocasiones detener a un proceso hasta que se produzca un determinado evento o se den ciertas condiciones à sincronización
8
Técnicas de sincronización
n Basadas en memoria compartida q Inhibición de Interrupciones q Espera activa q Semáforos q Regiones críticas q Monitores
n Basadas en el paso de mensajes q Canales q Buzones
9
Ejemplo 1: modificación concurrente de una variable
procedure Ejemplo1 is x:integer; procedure P1 is begin x:=x+10;
end P1; procedure P2 is begin if x>100 then Put_Line (x);
else Put_Line (x-‐50); end if; end P2;
begin x:=100; COBEGIN P1; P2; COEND;
end Ejemplo1;
10
Ejemplo 2: bucles infinitos concurrentes procedure Ejemplo2 is contador:integer;
procedure Cuenta is begin
loop …espera a que pase un coche… contador := contador+1; end loop;
end Cuenta; procedure Imprime; begin
loop espera una hora Put(“Coches que han pasado: “);
Put (contador); contador:=0 end loop;
end Imprime;
begin contador:=0; COBEGIN Cuenta; Imprime; COEND;
end Ejemplo2;
11
Ejemplo 3: búfer limitado
loop producir_algo (elem); loop
exit when contador<N; end loop; buffer(entra):=elem; entra:=entra+1; contador:=contador+1; end loop;
N: constant integer:=...; type elemento is ...; buffer: array(0..N-‐1) of elemento; entra,sale: mod N:=0; contador: integer range 0..N:=0;
loop loop
exit when contador>0; end loop; elem:=buffer(sale); sale:=sale+1; contador:=contador-‐1; consumir (elem); end loop;
Productor Consumidor
12
3
Problema al modificar datos compartidos
n Ambas rutinas son correctas si se ejecutan por separado pero podrían NO funcionar si se ejecutan de manera concurrente
n Supongamos que contador contiene en un momento dado el valor 5 y que las instrucciones “contador=contador+1” y “contador=contador-1” se ejecutan de forma concurrente (¡contador podría ser 4, 5 o 6!)
contador = contador + 1 contador=contador-1 registro1 := contador; registro2 := contador; registro1 := registro1 +1; registro2 := registro2 -1; contador : registro1; contador := registro2;
T0: productor registro1 := contador (registro1= 5) T1: productor registro1 := registro1+1 (registro1 = 6) T2: consumidor registro2 := contador (registro2 = 5) T3: consumidor registro2 := registro2 -1 (registro2 = 4) T4: productor contador := registro1 (contador = 6) T5: consumidor contador := registro2 (contador = 4)
13
Contenidos
n Sistemas concurrentes n El problema de la sección crítica n Semáforos n Monitores
14
Sección crítica: modelo del sistema n N procesos intentan acceder a un recurso
compartido en un bucle infinito: loop Sección_No_Crítica (SNC); Pre_Protocolo; Sección_Crítica (SC); Post_Protocolo; end loop;
n Sección crítica: segmento de código donde se accede a datos compartidos con otros procesos
15
Sección crítica: modelo del sistema (2) n Nunca puede haber más de un proceso en la
sección crítica (exclusión mutua) n Los pre y post protocolos serán algoritmos para
garantizar que se cumple la exclusión mutua
16
Requisitos de la solución
n Exclusión mutua n Progreso: si ningún proceso está en sección
crítica y hay procesos que desean entrar en su s.c., sólo estos últimos participarán en la decisión y ésta se tomará en un tiempo finito.
n Espera limitada: hay un límite para el número de veces que otros procesos pueden adelantarse a un proceso que quiere entrar en s.c.
17
Importante
n Suponemos que cada proceso se ejecuta a una velocidad distinta de cero
n No podemos hacer suposiciones acerca de las velocidades relativas de los procesos
18
4
Solución trivial: cortar la multiprogramación n Si suspendemos la multiprogramación,
desaparece el problema de acceso a los datos compartidos…
n …pero perdemos todas las ventajas de la multiprogramación
n Hay que buscar una solución menos radical
19
Solución del hardware: inhibir las interrupciones n Antes de que un proceso entre en su sección
crítica, se inhiben las interrupciones n Así es imposible que el proceso sea
expulsado de la CPU mientras está accediendo al dato compartido
n Al salir de la SC, se rehabilitan las interrupciones
20
Inhibir las interrupciones: problemas n Mientras un proceso está en SC, se
suspende toda la concurrencia en el sistema à no se le da oportunidad a otros procesos que no están accediendo al recurso compartido
n Esta técnica no se puede implementar en un multiprocesador
21
Soluciones con espera activa
n La sincronización se basa en que un proceso espera mediante la comprobación continua de una variable, manteniendo ocupada la CPU.
n Soluciones Software
n Soluciones Hardware
22
Intento ingenuo: usar un indicador de disponibilidad
23
-‐-‐ variable global -‐-‐ indica si la sección crítica está libre libre: boolean := true;
-‐-‐ código que ejecuta cada proceso loop … sección no crítica … loop exit when libre; end loop; libre := false; … sección crítica … libre := true; end loop;
loop SNC2; loop exit when turno=2;
end loop; SC2; turno:=1; end loop;
loop SNC1; loop exit when turno=1; end loop; SC1; turno:=2; end loop;
Primer intento serio: variable turno
turno: positive range 1..2 := 1;
24
(solución para dos procesos)
proceso 1 proceso 2
5
Discusión del primer intento
n ¿Exclusión mutua? n ¿Espera limitada? n ¿Progreso?
25
loop SNC1; loop exit when libre2; end loop; libre1:=false; SC1; libre1:=true; end loop;
loop SNC2; loop exit when libre1; end loop; libre2:=false; SC2; libre2:=true; end loop;
Segundo intento: avisadores
libre1, libre2: boolean := true;
26
proceso 1 proceso 2
Tercer intento
loop SNC1; libre1:=false; loop exit when libre2; end loop; SC1; libre1:=true; end loop;
loop SNC2; libre2:=false; loop exit when libre1; end loop; SC2; libre2:=true; end loop;
libre1,libre2: boolean := true;
27
proceso 1 proceso 2
loop SNC1; libre1:=false; turno:= 2; loop exit when libre2 or turno=1;
end loop; SC1; libre1:=true; end loop;
loop SNC2; libre2:=false; turno:= 1; loop exit when libre1 or turno=2;
end loop; SC2; libre2:=true; end loop;
Algoritmo de Peterson - ¡¡FUNCIONA!!
libre1, libre2: boolean := true; turno: positive range 1..2 := 1;
28
Solución para N procesos: Algoritmo de la panadería (Lamport)
cogiendonumero: array(1..N) of boolean := (others=>false); num: array(1..N) of natural := (others=>0);
29
loop –-‐ código del proceso “i” Sección no crítica (i); cogiendonumero(i):=true; num(i) := 1 + MAX(num(1) ... num(n)); cogiendonumero(i):=false; for j in 1..N loop loop exit when not cogiendonumero(j); end loop; loop exit when i=j or num(j)=0 or num(j)>num(i) or (num(j)=num(i) and j>i); end loop; end loop; Sección crítica (i); numero(i):=0; end loop;
Soluciones hardware
n Inhibir interrupciones (muy drástico)
n Instrucciones atómicas test-and-set o SWAP.
30
6
Instrucciones atómicas
n Inventadas en los años 60. n Permiten evaluar y asignar un valor a una
variable de forma atómica. n test-and-set(B): Pone B a true y devuelve el antiguo
valor de B. (Evaluar-y-Asignar(B)) n SWAP(A,B): Intercambia los valores de A y B.
(Intercambiar(A,B))
n Si disponemos de estas instrucciones, se simplifica muchísimo el problema de la sección crítica.
31
Ejemplos de algoritmos
loop Sección no crítica; loop exit when Test_and_Set(llave)=false; end loop; Sección crítica; llave:=false; end loop;
loop Sección no crítica; aux:=true; -‐-‐ ¡variable local! loop Swap(llave,aux); exit when aux=false; end loop; Sección crítica; llave:=false; end loop;
32
usando test-and-set
usando swap
Solución completa (test-and-set)
j: mod N; llave:boolean; loop SNCi; esperando(i):=true; llave:=true; while esperando(i) and llave loop llave:=Test_and_Set(cerradura); end loop; esperando(i):=false; SCi; j:=i+1; while (j/=i) and not esperando(j) loop j:=j+1; end loop; if j=i then cerradura:=false; else esperando(j):=false; end if; end loop;
esperando: array(0..N-‐1) of boolean := (others => false); cerradura: boolean := false;
33
Contenidos
n Introducción n El problema de la sección crítica n Semáforos n Monitores
34
Semáforos
n Edsger Dijkstra, 1965 n Objetivo: herramienta universal para
sincronizar procesos, que sirva como componente básico para construir algoritmos concurrentes
35
Concepto de semáforo
n Dijkstra lo definió como una variable entera S con dos operaciones atómicas:
n P(S): esperar a que S>0; S:=S-1;
n V(S): S:=S+1;
n NOTA: el semáforo no puede adquirir valores negativos
36
7
Semáforos: otras notaciones
n P(s) = wait(s) = espera (s) n V(s) = signal(s) = señal (s)
n (se utilizan varias notaciones para las operaciones de los semáforos, pero todas significan lo mismo)
37
Ejemplo: sección crítica resuelta con semáforos
n Usamos un único semáforo inicializado a uno.
begin Sección no crítica wait(s) Sección crítica signal(s) end;
38
Semáforos: esperar por eventos y condiciones n Se asocia un semáforo, inicializado a cero, al evento
por el que queremos esperar. Cuando un proceso ha hecho que se cumpla una determinada condición, lo indica ejecutando un signal(c). Un proceso esperará a que la condición sea cierta mediante un wait(c).
P1 begin S1; signal(c); S2;
end;
P2 begin R1; wait(c); R2;
end;
39
Semáforos: ejercicios
n Ejercicios q a.-) Resolver el problema de la sección crítica con n
procesos q b.-) Resolver diversos problemas de sincronización
n b.1.-) Sean P1 y P2 dos procesos concurrentes. Modificar el código de ambos procesos de forma que el conjunto de sentencias R2 del proceso 2 se ejecute después de que se haya ejecutado el conjunto de sentencias S1 del proceso 1.
P1 begin S1; S2; end;
P2 begin R1; R2; end;
40
Semáforos: ejercicios
q b.2.-) Realizar un pequeño programa que se ajuste al siguiente diagrama (o grafo) de precedencia (suponiendo que disponemos de las herramientas siguientes: sentencia concurrente cobegin/coend )
A
B
C
D
41
Semáforos: ejercicios
q b.3.-) Realizar un pequeño programa que se ajuste al siguiente diagrama (o grafo) de precedencia (suponiendo que disponemos de las herramientas siguientes: sentencia concurrente cobegin/coend y semáforos)
A
B
C
D
42
8
Semáforos: implementación con espera activa
wait(s): while s<=0 do nada; s:=s-‐1; signal(s): s:=s+1;
43
n También llamados spinlocks
Semáforos: implementación sin espera activa
n Suponemos que el SO proporciona unas operaciones para bloquear y desbloquear procesos
type Semáforo is record valor:integer; L: Lista<Proceso>;
end record;
signal(s): s.valor := s.valor+1;
if s.valor<=0 then L.extraer(proceso); despertar(proceso); end if;
wait(s): s.valor := s.valor-‐1; if s.valor<0 then L.insertar(procesoActual); bloquear(procesoActual); end if;
44
Semáforos: la implementación debe garantizar atomicidad n Es crítico que las operaciones se ejecuten
de forma atómica n Entorno uniprocesador:
q Inhibir interrupciones n Entorno multiprocesador:
q Instrucciones hardware especiales q Aplicar un algoritmo de sección crítica con
espera activa
45
Semáforos binarios
n Los semáforos vistos reciben el nombre de semáforo general o semáforo de conteo
n Un semáforo que sólo puede tomar los valores 0 y 1 recibe el nombre de semáforo binario
46
Ejercicio
n Implementación de un semáforo de conteo con semáforos binarios
47
Problemas clásicos de sincronización n Problema del búfer limitado n Problema de los lectores y escritores
q 1er problema: prioridad para los lectores q 2º problema: prioridad para los escritores
n Problema de los filósofos comensales
48
9
Búfer limitado
loop ... producir un elemento elem ... wait(hayHuecos); wait(cerradura); buffer(entra):=elem; entra:=entra+1; signal(cerradura); signal(hayElementos); end loop;
N: constant integer:=...; type elemento is ...; buffer: array(0..N-‐1) of elemento; entra,sale: mod N:=0; hayElementos: Semaphore :=0; hayHuecos: Semaphore :=N; cerradura: Semaphore :=1;
loop wait(hayElementos); wait(cerradura); elem:=buffer(sale); sale:=sale+1; signal(cerradura); signal(hayHuecos); ... consumir elemento elem ... end loop;
Productor Consumidor
49
Lectores y escritores
n Esquema útil para gestionar el acceso a una base de datos: q Puede haber varios lectores accediendo a la BD
de forma concurrente q Sólo puede haber un escritor trabajando q No puede haber lectores y escritores al mismo
tiempo q … y si se puede, que no haya inanición
50
Lectores y escritores: dos variantes n Primera variante: prioridad para los lectores
q Si un escritor está esperando, se le pueden adelantar otros lectores
q Ojo, riesgo de inanición para los escritores n Segunda variante: prioridad para los
escritores q Si hay escritores esperando por la BD, los
lectores que van llegando nuevos se deben esperar hasta que todos los escritores finalicen
q Ahora hay riesgo de inanición para los lectores
51
Lectores y escritores: 1ª variante
loop wait(cerradura); nlectores:=nlectores+1; if nlectores=1 then wait(escritura); signal(cerradura); LEER DE LA BD; wait(cerradura); nlectores:=nlectores-‐1; if nlectores=0 then signal(escritura); signal(cerradura); end loop;
cerradura: Semaphore :=1; escritura: Semaphore :=1; nlectores: natural :=0;
loop wait(escritura); ESCRIBIR EN LA BD; signal(escritura); end loop;
Lector Escritor
52
Lectores y escritores: 2ª variante
53
wait(cerrojo); while escribiendo or nesc>0 loop signal(cerrojo); wait(cerrojo); end loop; nlec := nlec + 1; signal(cerrojo); … leer de la BD … wait(cerrojo); nlec := nlec – 1; signal(cerrojo);
cerrojo : Semaphore := 1; escribiendo : boolean := false; nlec,nesc : natural := 0;
wait(cerrojo); nesc := nesc + 1; while escribiendo or nlec>0 loop signal(cerrojo); wait(cerrojo); end loop; nesc := nesc -‐ 1; escribiendo := true; signal(cerrojo); … escribir en la BD … wait(cerrojo); escribiendo := false; signal(cerrojo);
Lector Escritor
Los filósofos
54
10
Los filósofos: modelo simple
loop wait(palillo(i)); wait(palillo(i+1 mod 5)); ... COMER; ... signal(palillo(i)); signal(palillo(i+1 mod 5); ... PENSAR; ... end loop;
palillo: array(0..4) of Semaphore := (others=>1);
55
Filósofos: ojo al interbloqueo
n La solución anterior puede entrar en un estado de bloqueo mutuo entre todos los filósofos à interbloqueo
n Posibles soluciones: q Algoritmo asimétrico filósofos pares/impares q Impedir a más de cuatro filósofos entrar a pedir
los palillos q Coger los dos palillos de forma atómica (o coges
los dos, o no coges ninguno)
56
Los semáforos ayudan, pero tienen limitaciones…
n Los semáforos son una herramienta de bajo nivel, que requiere un uso disciplinado y cuidadoso.
n Es muy fácil cometer errores de uso con semáforos.
n Veamos algunos ejemplos…
57
¿dónde está el fallo?
Sem = 0 P (sem) … sección crítica … V (sem)
58
¿dónde está el fallo?
Sem = 1 void rutina_en_exclusion_mutua () { P (Sem) … código de sección crítica if ( error ) return; … más código de sección crítica V (sem) }
59
Más problemas…
Proceso 1 P (impresora) P ( disco ) … usar disco e impresora
V (disco) V (impresora)
Proceso 2 P (disco) P ( impresora ) … usar disco e impresora
V (impresora) V (disco)
60
Dos procesos que acceden a recursos compartidos: ¿qué ocurre al ejecutarlos al mismo tiempo?
11
Herramientas de alto nivel
n Objetivo: introducir en el lenguaje de programación herramientas de sincronización que sean más seguras que los semáforos
n Ejemplos: q Regiones críticas q Monitores y variables condición
61
Regiones críticas condicionales
n Abstracción de un bloque de código que accede a recursos compartidos.
n Garantiza exclusión mutua. n El código sólo se ejecuta si la condición
asociada a la región crítica es cierta. n Ejemplo:
region Búfer when Nelementos > 0 { // este código se ejecuta en exclusión mutua // y sólo se ejecuta si Nelementos > 0 … consumir un elemento del búfer … Nelementos = Nelementos – 1; }
62
Regiones críticas condicionales
n Se plantearon en 1972 (Brinch Hansen, Pascal Concurrente)
n Gran fuerza expresiva, el código queda mucho más legible y compacto
n Problema: implementación muy costosa, comparada con el código escrito a mano con semáforos
n Por ese motivo, nunca llegaron a prosperar como herramienta de uso común
63
Contenidos
n Introducción n El problema de la sección crítica n Semáforos n Monitores
64
Monitor
n Propuesto por Hoare (1972) n Tipo abstracto de datos
q Estructura de datos privada q Operaciones públicas
+ q Exclusión mutua q Sincronización (variables condición)
65
Monitor: ejemplo básico
66
monitor Contador { // operaciones públicas public Contador () { valor = 0; } public void incrementa() { valor++; } public int actual() { return valor; } int valor; // variable interna privada }; Contador.incrementa(); V = Contador.actual(); Si varios procesos intentan manipular el monitor al mismo tiempo, van entrando de uno en uno: no puede haber más de un proceso trabajando con el monitor en cada momento.
12
Monitor: estructura interna
67
Variables condición
n Una variable condición sirve para gestionar una cola de espera por el monitor
n Dos operaciones q x.wait à bloquea al proceso y lo mete en la cola “x”
q x.signal à desbloquea a un proceso de la cola “x”; si no hay procesos en “x”, no hace nada
68
Variables condición: ejemplo
69
monitor Contador { Condition cola; public Contador () { valor = 0; } public void BloqueaHastaQueValgaDiez() { if ( valor < 10 ) { cola.wait(); } } public void Incrementa() { valor++; if ( valor == 10 ) { cola.signal(); } } int valor; };
Monitor con variables condición
código de inicialización
x y
datos compartidos
colas asociadas a las variables condición x e y
cola de ingreso
...
operaciones
70
Qué ocurre tras un “signal”
n ¿ Qué ocurre cuando un proceso P realiza una operación signal sobre una variable condición x y existe un proceso suspendido Q asociado a dicha variable?
n Estilo Hoare à se reanuda Q inmediatamente n Estilo Mesa à Q se desbloquea, pero espera a que
P abandone el monitor
n El estilo Mesa es el más utilizado en los lenguajes de programación actuales
71
Qué ocurre tras un “signal” (2)
n Si varios procesos están suspendidos por la condición x y algún proceso ejecuta x.signal, ¿ qué proceso se reanuda? q FIFO à desbloqueamos al más antiguo q Por prioridades à conveniente en sistemas de
tiempo real
72
13
Ejemplo: un semáforo implementado con un monitor
73
monitor Semáforo { int valor; Condition cola; public Semáforo (int val) { valor = val; } public void P() { while ( valor == 0 ) { cola.wait(); } valor-‐-‐; } public void V() { valor++; cola.signal(); } };
Ejemplo: búfer limitado
74
monitor Búfer { Condition hayHuecos, hayItems; int nitems = 0; const int N = …; public void insertar (Item x) { while ( nitems==N ) { hayHuecos.wait(); } … introducir x en el búfer … nitems++; hayItems.signal(); }
public Item extraer() { while ( nitems==0 ) { hayItems.wait(); } Item x = … extrae algo … nitems-‐-‐; hayHuecos.signal(); return x; } };
Cómo se implementa un monitor
75
monitor MiMonitor { public void oper1 (…) { … } public void oper2 (…) { … } };
class MiMonitor { Semáforo cerrojo = 1; public void oper1 (…) { cerrojo.P(); … cuerpo de oper1 … cerrojo.V(); } public void oper2 (…) { cerrojo.P(); … cuerpo de oper2 … cerrojo.V(); } };
El compilador genera un código parecido a este:
El cerrojo garantiza que no puede haber más de un proceso dentro del monitor
Cómo se implementa un monitor: variables condición
76
monitor MiMonitor { Condition c; … c.wait(); … c.signal(); … };
monitor MiMonitor { Semáforo cerrojo = 1; Semáforo c_queue = 0; int c_count = 0;
c_count++; cerrojo.V(); // 1. libero el monitor c_queue.P(); // 2. me bloqueo en la cola cerrojo.P(); // 3. cuando me desbloqueen // debo recuperar el monitor
if (c_count>0) { // si hay alguien esperando c_count-‐-‐; // lo desmarco c_queue.V(); // y lo desbloqueo }
Monitores: ejemplos más avanzados
77
Lectores y escritores (1)
78
monitor BaseDatos { public EmpiezaLectura() { … } public TerminaLectura() { … } public EmpiezaEscritura() { … } public TerminaEscritura() { … } }; void Leer() { // Lo que debe ejecutar un lector BaseDatos.EmpiezaLectura(); … leer de la BD … BaseDatos.TerminaLectura(); } void Escribir() { // Lo que debe ejecutar un escritor BaseDatos.EmpiezaEscritura(); … escribir en la BD … BaseDatos.TerminaEscritura(); }
14
Lectores y escritores (2)
79
monitor BaseDatos { Condition leer, escribir; int nlec=0, lecesperan=0; bool escribiendo = false; public EmpiezaLectura() { while (escribiendo) { lecesperan++; leer.wait(); lecesperan-‐-‐; } nlec++; leer.signal(); // desbloquea en cadena al resto } public TerminaLectura() { nlec-‐-‐; if (nlec==0) { escribir.signal(); } }
Lectores y escritores (y 3)
80
public EmpiezaEscritura() { while (nlec>0 || escribiendo) { escribir.wait(); } escribiendo = true; } public TerminaEscritura() { escribiendo = false; if (lecesperan > 0) { leer.signal(); } else { escribir.signal(); } } };
Filósofos (1): especificación del monitor
81
monitor MesaFilósofos {
// estado interno del sistema const int N=5; Condition puedeComer[N]; enum Estado { pensando, hambriento, comiendo }; Estado estado[N] = { others => pensando };
// operaciones públicas (ver siguientes páginas) public CogePalillos ( int filosofo ) { … } public SueltaPalillos ( int filosofo ) { … } // operación auxiliar interna private compruebaQuePuedeComer ( int filosofo ) { … }
};
Filósofos (2): ejemplo de uso
82
void VidaDelFilósofo ( int unFilosofo ) { loop { piensaUnPoco(); MesaFilósofos.CogePalillos (unFilosofo); comeArroz(); MesaFilósofos.SueltaPalillos (unFilosofo); } }
Filósofos (3): rutina auxiliar
83
// operación privada dentro del monitor MesaFilósofos
private compruebaQuePuedeComer ( int filosofo ) { int vecinoDerecha = (filosofo+1) % N; int vecinoIzquierda = (filosofo-‐1+N) % N; if ( estado[vecinoIzquierda] != comiendo && estado[vecinoDerecha] != comiendo ) { estado[filosofo] = comiendo; puedeComer[filosofo].signal(); } }
Filósofos (y 4): operaciones públicas del monitor
84
public CogerPalillos ( int filosofo ) { estado[filosofo] = hambriento; compruebaQuePuedeComer(filosofo); if ( estado[filosofo] != comiendo ) { puedeComer[filosofo].wait(); } } public SoltarPalillos ( int filosofo ) { estado[filosofo] = pensando; int vecinoDerecha = (filosofo+1) % N; int vecinoIzquierda = (filosofo-‐1+N) % N; compruebaQuePuedeComer (vecinoDerecha); compruebaQuePuedeComer (vecinoIzquierda); }