Febrero 2008 2ª Semana

Anuncio
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
1. Equivalencia de herramientas. Implemente las primitivas de los buzones mediante monitores.(2pt).
monitor mibuzon;
const MAXBUZON = ...;
export send, receive, empty;
var buffer : array[1..MAXBUZON] of item;
lleno, vacio : condition;
frente, cola, nelem : int;
procedure send(cosa : item);
begin
if (nelem = MAXBUZON) then delay(lleno);
buffer[frente] := cosa;
frente := (frente + 1) mod MAXBUZON;
resume(vacio);
end
procedure receive(var cosa : item);
begin
if (frente = cola) then delay(vacio);
cosa := buffer[cola];
cola := (cola + 1) mod MAXBUZON;
resume(lleno);
end
funcion empty : bool;
begin
return (frente = cola);
end;
begin
frente := 0;
cola := 0;
nelem := 0;
end;
2. Se dice que un número natural mayor que cero es un número perfecto si es la
suma de todos sus divisores excepto él. Por ejemplo, los divisores de 6 son 1,2,3 y
6. Como 1+2+3=6, 6 es un número perfecto. Vamos a hacer un programa con una
estructura determinada que calcule los números perfectos entre 1 y n mediante
paso de mensajes.
1
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
Cada número, i, entre 1 y n, va estar representado por un proceso al que llamaremos proceso i-ésimo. El proceso i-ésimo hará lo siguiente: Para k, que variará entre
los múltiplos de i menores o iguales que n pero distintos del propio i, el proceso
enviará un mensaje al proceso k-ésimo cuyo contenido es i. Por otra parte, también
recibirá los mensajes de sus compañeros e irá sumando la información de los mensajes recibidos para formar la suma de sus divisores. El proceso i-ésimo también
enviará un mensaje a todos los procesos j-ésimos, con j > i, con el contenido ”0” para marcar el final de la comunicación con ese proceso. Cuando un proceso i-ésimo
haya recogido el número adecuado de mensajes con contenido nulo, sabrá que ha
recibido todos los mensajes que necesitaba. En ese momento enviará la información
de si es un número perfecto o no a un proceso controlador y terminará.
El proceso controlador recibirá los mensajes de los procesos, imprimirá por pantalla quiénes son los números perfectos y cuando los haya imprimido todos terminará.
Escriba un programa concurrente en pseudocódigo para modelizar el cálculo
descrito, utilizando exactamente dos tipos de proceso: i-ésimo y controlador. No
puede utilizar memoria compartida. Si en la práctica obligatoria de la asignatura
utilizó semáforos, utilice la invocación remota. Si en la práctica obligatoria de la
asignatura utilizó monitores, entonces utilice buzones. Si utilizó semáforos y monitores juntos entonces está usted suspenso en esta convocatoria y puede volver a
realizar la práctica para la convocatoria de septiembre.
La solución debe contar con unas estructuras de datos que permitan resolver cabalmente el problema. Se prestará atención para evitar situaciones de interbloqueo,
inanición y espera activa. Asimismo, se debera 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. (8pt).
Este sería el programa mediante invocación remota:
program perfecto;
const
N = 1000000;
process type k-esimo(k : int)
var
i, nceros, suma : int;
begin
2
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
i := 2;
nceros := 0;
suma := 0;
// Enviamos los mensajes a los multiplos mientras no tengamos
// invocaciones de otros procesos, si las hay las atendemos primero
while i*k <N do
select
accept enviar(h : int) do
begin
suma := suma + h;
if h = 0 then nceros := nceros + 1;
end
else
begin
k-esimo[i*k].enviar(k);
i := i + 1;
end
end-select
i := k+1;
// Enviamos los mensajes de fin de comunicacion mientras no haya llamadas
// remotas que atender
while i <= N do
select
accept enviar(h : int) do
begin
suma := suma + h;
if h = 0 then nceros := nceros + 1;
end
else
begin
k-esimo[i].enviar(0);
i := i+1;
end;
end-select
// Atendemos las ultimas llamadas
while nceros <>k - 1 do
begin
accept enviar(h : int) do
begin
3
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
suma := suma + h;
if h = 0 then nceros := nceros +1;
end
end;
// Si el numero es perfecto avisamos al controlador
if (suma = k) then controlador.perfecto(k);
end;
process controlador;
begin
repeat
select
accept perfecto(h : int) do
writeln(’El numero ’, h, ’ es perfecto’);
or terminate
end-select
forever
end;
numeros : array[1..N] of k-esimo;
cobegin
controlador;
for i := 1 to N do
numeros[i](i);
coend
end.
Y este sería el programa mediante buzones
program perfecto;
const
N = 1000000;
// Cualquier valor entre 1 y 2*N es adecuado. Cuanto mayor el tamaño dentro de
// esos limites, mayor sera la concurrencia
TAMBUZON=...;
var
buzones : array[1..N] of mailbox[TAMBUZON] of int;
control : mailbox[1] of int;
i : int;
4
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
// El proceso que representa al numero k-esimo
process type k-esimo(k : int);
var
i, h, nceros, suma : int;
begin
i := 2;
nceros := 0;
suma := 0;
// Vamos a enviar los mensajes a los multiplos.
// Intercalamos la recepcion de mensajes para aumentar la concurrencia
while i*k <N do
begin
send(buzones[i*k], k);
if not empty(buzones[k])
begin
receive(buzones[k], h);
suma := suma + h;
if h = 0 then nceros := nceros + 1;
end;
i := i + 1;
end
// Ahora enviamos el mensaje de fin de comunicacion a los numeros mayores que k
// Tambien intercalamos la recepcion de mensajes para aumentar la concurrencia
i := k + 1;
while i <= N do
begin
send(buzones[i], 0);
if not empty(buzones[k])
begin
receive(buzones[k], h);
suma := suma + h;
if h = 0 then nceros := nceros + 1;
end;
i := i + 1;
end;
// Y recibimos los ultimos mensajes
while nceros <>k - 1 do
begin
5
Examen de Programación Concurrente: Segunda Semana Febrero 2008
David Fernández Amorós
receive(buzones[k], h);
suma := suma + h;
if h = 0 then nceros := nceros + 1;
end;
if suma = k then send(control, k);
end.
numeros : array[1..N] of k-esimo;
process controlador;
var
k : int;
begin
repeat
select
receive(control, k);
writeln(’El número ’,k, ’ es perfecto.’);
or terminate
end-select
forever
end;
cobegin
controlador;
for i := 1 to N do
numeros[i](i);
coend
end.
6
Descargar