1. Se desea resolver el problema del productor

Anuncio
Examen de Programación Concurrente: Septiembre 2008
David Fernández Amorós
1. Se desea resolver el problema del productor-consumidor usando semáforos
para enviar y recibir. Hay un solo emisor y un solo receptor y las operaciones
que realizan son enviar y recibir respectivamente. La información que se envía
se pasa a través de una variable compartida, en este caso valor, por lo que el
buffer de comunicación tiene longitud uno. El protocolo es síncrono, esto quiere
decir que el primer proceso, ya sea el productor o el consumidor que llega a la
cita tiene que esperar al otro. Rellene el hueco en el pseudocódigo del procedimiento recibir para lograr este objetivo. (2pt)
var primero : boolean;
mutex : semáforo;
segundo : semáforo;
valor : entero;
procedure enviar(v:entero);
begin
wait(mutex);
valor := v;
if primero then
begin
primero := false;
signal(mutex);
wait(segundo);
signal(mutex);
end
else
begin
primero := true;
signal(segundo);
end
end;
procedure recibir(var v:
entero);
begin
wait(mutex);
if primero then
...
else
begin
primero := true;
v := valor;
signal(segundo);
end
end
proceso productor;
var i: entero;
begin
for i := 1 to 10 do
enviar(i)
end;
proceso consumidor;
var i,v : entero;
begin
for i := 1 to 10 do
begin
recibir(v);
writeln(v)
end
end;
begin
primero := true;
init(mutex,1);
init(segundo,0);
cobegin
productor;
consumidor;
coend
end.
El texto que corresponde a los puntos suspensivos es el siguiente:
begin
primero := false;
signal(mutex);
wait(segundo);
v := valor;
signal(mutex);
end
2. Un lobo y un cordero acudieron a la orilla del mismo río, empujados por
1
Examen de Programación Concurrente: Septiembre 2008
David Fernández Amorós
la sed. El lobo estaba arriba del curso del río y el cordero mas abajo. El lobo
imaginó un simple pretexto a fin de devorarlo. Así, dijo el lobo:
– Cordero, me enturbias el agua.
– Pero, ¿cómo puedo hacer eso que dices, lobo, si estoy más abajo?
Viéndose el lobo burlado, insistió:
– Hace seis meses insultaste a mis padres.
– ¡ Pero por aquel entonces yo ni siquiera había nacido ! – contestó el cordero.
Dijo entonces el lobo:
– Entonces sería tu hermano. De todas formas serás mi cena.
Y se lo comió.
Desde entonces, los corderos han modificado su patrón de conducta para no
quedarse a solas con un lobo. Un lobo va a beber al río cuando tiene sed y bebe.
Si hubiera un cordero solo, entonces se lo comería y se iría, pero si hay varios
corderos no se come a ninguno y se va, hasta que vuelve a tener sed, momento
en el cual se repite la misma historia. A un lobo no le afecta que haya otros lobos
en el río.
El comportamiento de los corderos también implica que periódicamente tienen sed y quieren beber en el río. Después de beber se van, hasta que vuelven a
tener sed.
a. Piense una estrategia para los corderos que garantice su supervivencia, es
decir, que nunca se va a quedar solo un cordero en el río en presencia de
uno o varios lobos. Describa brevemente dicha estrategia. (2pt).
Para los lobos no hace falta ninguna estrategia, la cuestión recae por entero
en los corderos. Lo más sencillo es considerar el río como un recurso. Necesitaremos un protocolo de entrada al río y otro de salida.
A la hora de entrar hay dos posibilidades: La primera es que haya más de un
cordero bebiendo. En ese caso podemos entrar a beber sin más. La segunda
es que no haya ninguno bebiendo. Este caso se subdivide en otros dos, dependiendo de que haya otro cordero esperando para acercarse al río o no. Si no
hay otro corderos esperando, entonces toca esperar, pero si hay otro cordero
esperando para acceder al río, los dos entran al río al mismo tiempo. Además,
2
Examen de Programación Concurrente: Septiembre 2008
David Fernández Amorós
si hay algún cordero esperando salir del río, después de entrar es el momento
para avisarlo de que ya puede irse.
En el caso principal no hay que considerar la posibilidad de que sólo haya un
cordero bebiendo porque esa estrategia no es robusta, ya que en cualquier
momento podría aparecer un lobo y comerse al cordero.
Para el protocolo de salida, la situación es similar. Si hay más de dos corderos
bebiendo, entonces la salida es posible directamente. Si sólo hay dos corderos,
hay dos posibilidades: Si no hay nadie esperando para salir, el cordero se
queda a la espera. Si ya hay uno esperando, entonces se le avisa y salen los
dos a la vez.
b. Se pide simular el comportamiento de un grupo de diez lobos y diez corderos mediante un programa concurrente escrito en pseudocódigo, utilizando
los tipos de proceso lobo y cordero, de forma que el comportamiento de los
lobos se ajuste a lo descrito en el enunciado y el de los corderos se ajuste
tanto a lo indicado en el enunciado como a la estrategia de supervivencia
desarrollada en el punto anterior. Puede elegir para la implementación entre semáforos y monitores (no una mezcla de ambos). Para seguir la simulación, los procesos deben emitir unos mensajes por pantalla que expliquen
razonablemente lo que están haciendo.
La solución debe contar con unas variables y estructuras de datos que permitan resolver razonablemente el problema. Es vital que se respete escrupulosamente la exclusión mutua en el manejo de las variables compartidas.
Además, se prestará atención para evitar situaciones de interbloqueo y espera activa. Asimismo, se deberar procurar alcanzar un alto grado de concurrencia entre los procesos y una correcta sincronización entre los mismos.
Si se identifica un problema-tipo, debe mencionarse explícitamente (incluyendo, en su caso, la prioridad más adecuada) antes de proceder con el
pseudocódigo. Es muy importante que el comportamiento de los procesos
se ajuste al enunciado, tanto en los aspectos específicamente concurrentes
como en los demás. (6pt)
En primer lugar, hay que decir que este problema no corresponde a ninguno de
los dos problemas-tipo estudiados en la asignatura. Es cierto que tiene un lejano
parecido con el de los lectores y escritores, pero también hay sutiles diferencias
que hacen que la solución de aquel no pueda adaptarse fácilmente a este.
Una solución empleando un monitor es la siguiente:
3
Examen de Programación Concurrente: Septiembre 2008
David Fernández Amorós
delay(salir);
writeln(’Soy el cordero ’,id, ’ y
salgo del rio’);
dentro := dentro - 1;
end;
program lobosycorderos;
monitor rio;
export corderoEntrar, corderoSalir,
loboEntrar, loboSalir;
begin
dentro := 0;
end;
var entrar, salir : condition;
dentro : integer;
procedure loboentrar(id: integer);
begin
writeln(’Soy el lobo ’,id, ’ y entro a beber en el rio’);
if dentro = 1 then
writeln(’Soy el lobo ’,id, ’ y
me como al cordero. Estrategia incorrecta’);
end;
procedure lobosalir(id : integer);
begin
writeln(’Soy el lobo ’,id, ’ y salgo de beber en el rio’);
end;
procedure corderoEntrar(id:integer);
begin
writeln(’Soy el cordero ’,id, ’ y
tengo ganas de beber’);
resume(entrar);
if dentro = 0 then
delay(entrar);
writeln(’Soy el cordero ’,id, ’ y
entro al rio’);
dentro := dentro + 1;
resume(salir);
end;
procedure corderoSalir(id: integer);
begin
writeln(’Soy el cordero ’,id, ’ y
quiero salir del rio’);
resume(salir);
if dentro = 2 then
process type lobo(id : integer);
begin
repeat
rio.loboEntrar(id);
rio.loboSalir(id);
forever
end;
process type cordero(id : integer);
begin
repeat
rio.corderoEntrar(id);
rio.corderoSalir(id);
forever;
end;
var
lobos : array [1..10] of lobo;
corderos : array [1..10] of cordero;
bucle : integer;
(* Programa principal *)
begin
cobegin
for bucle:= 1 to 10 do
begin
lobos[bucle](bucle);
corderos[bucle](bucle);
end;
coend;
end.
4
Descargar