PROBLEMA DE LOS FILOSOFOS COMENSALES

El problema de la cena de los filósofos. Cinco filósofos se sientan en una mesa redonda. En el centro de la mesa hay un plato de arroz. El arroz es tan escurridizo que un filósofo necesita dos palillos para comerlo, pero cada filosofo solo posee un palillo, luego existe el mismo número de filósofos que de palillos. La vida de un filósofo consta de periodos alternados de comer y pensar. Cuando un filósofo siente hambre, intenta coger el palillo de la izquierda y si lo consigue, lo intenta con el de la derecha. Si logra asir dos palillos toma unos bocados y después deja los cubiertos y sigue pensando.

La solución de este problema se basa en implementar un algoritmo eficiente en el manejo de semáforos y memoria compartida que seguidamente describimos. A lo largo del programa se utilizan funciones necesarias para el manejo de memoria compartida (véase "rshmem.h Y "rshmem.c") manejo de semáforos (véase "semaph.c" .)

Se considera a cada filósofo como un proceso y a su vez como un metodo de freno para los filosofos vecinos, es decir que si un filosofo esta comiendo, este hecho impide que puedan comer cualquiera de los dos filosofos que estan a su lado. De modo que, para que un proceso acceda al recurso que necesita, el palillo en este caso, tenemos que considerar que cada filosofo es un semáforo. Este semáforo es binario y vale 0 si el filosofoso poseedor del palillo está comiendo, o intentandolo y 1 si el filosofo está meditando

<Ver programa "fuentes.c" ,>

Creación de un proceso padre y de sus N procesos hijos (filósofos).

NOMBRE

incrementa;

filosofo;

incrementa ( int * mem , int k );

void filosofo( FILE *pf , key_t *sclave, int *sfilo, int i, int *comer, int *fin, int *fc);

incrementa( ); Esta función implementa el acceso a un recurso compartido, que será la variable que contabiliza el total de veces que comen todos los filósofos. En esta función se han incluido varias llamadas al macro TP. Este macro implementa un retardo aleatorio con el fin de dar cierto tiempo a que ocurran interrupciones que puedan detener la ejecución del proceso en su "cuanto" de tiempo asignado por el S.O.. En nuestro caso, es necesario realizar unas cuantas llamadas para dar tiempo a que todos los filósofos tengan oportunidad de comer. filosofo( ); Permite que el filósofo pueda acceder a los dos palillos que necesita (izquierda y derecha) y coma. Una vez que acaba de comer se encarga de dejar los palillos útiles para que sean de nuevao utilizados (por él o por otros). Para ello se basa en funciones de manejo de semáforos y memoria compartida. Los argumentos que se le pasan son los siguientes: pf: el fichero de salida sclave: la clave de los semaforos sfilo: los semaforos i: el numero anterior al filosofo en cuestion que desea comer comer: el numero de veces que han comido todos los filosofos fin: marca la salida de todos los procesos fc: (filosofos comiendo) es una marca para evitar el abrazo mortal, pues se vigila que no haya mas de (N+1)/2 filosofos intentando comer a la vez.

Utiliza las siguientes funciones:

Manejo de semaforos:

•semWait ( ) •semSignal ( ) •semOpen ( ) •semClose ( )

Manejo de memoria compartida:

•incrementa ( )

Cada vez que come un filósofo lo refleja en el incremento de la variable de memoria compartida.

Cuando los filósofos han comido un número M de veces prefijado se lo comunican al padre, no sin antes haber cerrado adecuadamente todos los semáforos utilizados en esta función.

•En la función filósofo es necesario incluir un exit(1); para que no se produzcan infinitas copias del proceso padre. Ya que , al estar dentro de un bucle iterativo , sino indicamos que el proceso hijo ha finalizado su trabajo, éste crearía otros procesos hijos iguales al él. Y asi sucesivamente.

•Para evitar que se produzca un dead_lock (abrazo mortal) he introducido la variable fc, la cual es un contador de los filosofos que intentan comer a la vez y se actualiza cuando el filosofo en cuestion coge o suelta el palillo que le pertenece. Asi cuando mas de la mitad de los filosofos sentados a la mesa intentan comer a la vez dicha variable se lo impide y le obliga a soltar el palillo que posea en la mano (pues solo tendra uno) El abrazo mortal se produce cuando todos los filósofos han cogido al mismo tiempo su palillo izquierdo, con lo cual, ninguno puede coger el derecho.

ficheros:

•<stdlib.h> •"rshmem.h" •"rshmem.c" •"semaph.c" •<sys/sem.h> •<math.h> •<time.h>

macros:

•N número de filósofos en la mesa •M número total de veces que comen •TP

variables de memoria compartida:

•comer •fin •fc

Si quieres ver los ficheros fuentes.c , luego para el uso de la memoria compartida puedes echarle un ojo

a los ficheros rshmem.c y rshmem.h , y para el uso de semaforos semaph.c

el programa crea un fichero de salida, "fich", con un listado del orden por el cual han comido los filosofos

VALLADOLID, 15 DE JUNIO DE 1998.

ANTONIO POVEDANO MARTINEZ

povedano@mailcity.com