Sei sulla pagina 1di 6

UNIVERSIDAD NACIONAL JORGE BASADRE GROHMANN

FACULTAD DE INGENIERA
ESCUELA ACADMICO PROFESIONAL DE INGENIERA EN
INFORMTICA Y SISTEMAS

PROBLEMA DE LOS CANBALES


SEMFOROS Y MONITORES

CURSO: ALGORITMOS Y PROGRAMACIN PARALELA


DOCENTE: Ing. MARIO GAUNA CHINO
ESTUDIANTE: DIEGO ALEXANDER ESTRADA CRUZ || 2014-119064
AO: SEGUNDO | TURNO: TARDE | GRUPO: B
FECHA DE ELABORACIN: 27/11/2015
FECHA DE ENTREGA: 01/12/2015

TACNA PER

2015

El Problema de los Canbales


Los Canbales Comensales
1. INTRODUCCIN
En una tribu de canbales todos comen de la misma olla, la cual puede albergar N
raciones de comida. Cuando un canbal quiere comer, simplemente se sirve de la olla
comn, a no ser que est vaca. En ese caso, el canbal despierta al cocinero de la tribu y
espera hasta que ste haya rellenado la olla.
En este problema, los eventos de sincronizacin son dos:

Si un canbal que quiere comer se encuentra con la olla vaca, entonces se lo


notifica al cocinero para que ste cocine.
Cuando el cocinero termina de cocinar, entonces se lo notifica al canbal que lo
despert previamente.

Un posible planteamiento para solucionar este problema podra girar en torno al uso de
un semforo que controlara el nmero de raciones disponibles en un determinado
momento (de manera similar al problema del buffer limitado). Sin embargo, este
planteamiento no facilita la notificacin al cocinero cuando la olla est vaca, ya que no
es deseable acceder al valor interno de un semforo y, en funcin del mismo, actuar de
una forma u otra.
Una alternativa vlida consiste en utilizar el patrn marcador para controlar el nmero
de raciones de la olla mediante una variable compartida. Si sta alcanza el valor de 0,
entonces el canbal podra despertar al cocinero.
La sincronizacin entre el canbal y el cocinero se realiza mediante rendezvous (cita):
1.

El canbal intenta obtener una racin.

2.

Si no hay raciones en la olla, el canbal despierta al cocinero.

3.

El cocinero cocina y rellena la olla.

4.

El cocinero notifica al canbal.

5.

El canbal come.

2. APLICANDO USO DE SEMFORO


2.1.

Elementos
Num_Raciones, variable compartida que contiene el nmero de raciones
disponibles en la olla en un determinado instante de tiempo.
Mutex, semforo binario que controla el acceso a Num_Raciones.
Empty, que controla cuando la olla se ha quedado vaca.
Full, que controla cuando la olla est llena.

2.2.

Seudocdigo
En el siguiente listado se muestra el pseudocdigo del proceso cocinero, el
cual es muy simple ya que se basa en esperar la llamada del canbal, cocinar
y notificar de nuevo al canbal.
a) Proceso Cocinero

El pseudocdigo del proceso canbal es algo ms complejo, debido a que ha


de consultar el nmero de raciones disponibles en la olla antes de comer.
b) Proceso Canbal

Como se puede apreciar, el proceso canbal comprueba el nmero de raciones


disponibles en la olla (lnea [4]). Si no hay, entonces despierta al cocinero (lnea
[5]) y espera a que ste rellena la olla (lnea [6]). Estos dos eventos de
sincronizacin guan la evolucin de los procesos involucrados.
Note cmo el proceso canbal modifica el nmero de raciones asignando un valor
constante. El lector podra haber optado porque fuera el cocinero el que
modificara la variable, pero desde un punto de vista prctico es ms eficiente que
lo haga el canbal, ya que tiene adquirido el acceso a la variable mediante el
semforo mutex (lnea [2] y [12]).
Posteriormente, el canbal decrementa el nmero de raciones (lnea [12]) e
invierte un tiempo en comer (lnea [14]).

3. APLICANDO USO DE MONITORES


3.1.

Ejemplo

Una tribu de N canbales come de una gran marmita comn con capacidad para
6 comensales simultneos.
Cuando un comensal quiere comer, come de la marmita, a menos que no haya
suficiente comida para l. Si no hay suficiente comida en la marmita, el canbal
despierta al cocinero y espera a que el cocinero haya rellenado la marmita con
la carne de los misioneros capturados (no debe haber notificaciones repetidas).
Para rellenar la marmita el cocinero debe esperar a que todos los comensales
que se encuentran actualmente comiendo terminen. El comensal que avis debe
ser el primero en comer.
El cocinero, por su parte, vuelve a dormir cuando ha rellenado la marmita.
Cada cierto tiempo llega el jefe de la tribu el cual debe esperar que todos los
comensales terminen para comer solo, teniendo ste prioridad sobre los nuevos
comensales.
3.2.

Consideraciones

No podrn entrar nuevos comensales a la marmita en las siguiente situaciones:


- El jefe est comiendo o esperando para comer.
- El cocinero est rellenando o esperando para rellenar.
El jefe se comporta como un comensal ms para el cocinero y tambin fue el
primero en avisarle.
Se supone que la marmita llena dispone de comida para ms de seis canbales.
3.3.

Funciones

o Hay_suficiente_comida (): boolean


Esta funcin es ejecutada por los comensales (canbales y el jefe) retorna si hay
suficiente comida en la marmita. No puede ser ejecutada por dos o ms
comensales a la vez.
o Rellenar (): Esta funcin es ejecutada por el cocinero.
o Comer (): Es ejecutado por los comensales.
o Ocio (): Ejecutada por los canbales y el jefe cuando no estn comiendo.
Se pide:
Implementar los procedimientos canbal, jefe y cocinero utilizando monitores.
Especifique la semntica de los mismos en caso de ser necesario.

3.4.

Solucin

program Marmita;
begin
var cant_canibales: integer;
var jefe, rellenar: boolean;
var cnd_jefe, cnd_relleno, cnd_cocinero, cnd_canibal:
condition;
procedure comer (soy_jefe: boolean);
begin
if soy_jefe then
begin
jefe = true;
if cant_canibales > 0 or rellenar do
cnd_jefe.wait();
end;
else
if cant_canibales = 6 or rellenar or jefe do
cnd_canibal.wait();
if not hay_suficiente_comida() then
begin
rellenar = true;
if cant_canibales = 0 then
cnd_cocinero.signal();
cnd_relleno.wait();
end;
if not jefe and not rellenar and cant_canibales < 6 then
cnd_canibal.signal();
cant_canibales++;
end;
procedure termine_comer (soy_jefe: boolean);
begin
if soy_jefe then
jefe = false;
cant_canibales--;
despertar();
end;
procedure cocinero_inicio();
begin
cnd_cocinero.wait();
end
procedure cocinero_fin();
var i: integer;
begin
rellenar = false;
cnd_relleno.signal(); // prioridad mxima al que avis
despertar();
end;
procedure despertar();
begin
if cant_canibales = 0 then
begin

if rellenar then
cnd_cocinero.signal();
else if jefe then
cnd_jefe.signal();
end;
if not jefe and not rellenar then
cond_canibal.signal();
end;
begin
cant_canibales = 0;
jefe = false;
rellenar = false;
end;
end;
procedure canibal ();
begin
while true do
begin
marmita.comer(false);
comer();
marmita.termine_comer(false);
ocio();
end;
end;
procedure jefe ()
begin
while true do
begin
marmita.comer(true);
comer();
marmita.termine_comer(true);
ocio();
end;
end;
procedure cocinero ()
begin
while true do
begin
marmita.cocinero_inicio();
rellenar();
marmita.cocinero_fin();
end;
end.

Potrebbero piacerti anche