Está en la página 1de 5

Filósofos comenzales.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

/*
Ejemplo 2.1
Programa para el problema de la cena de los filósofos. Cuando se invoca al
programa se debe hacer con un argumento que indique el número de filósofos q
ue
queremos considerar. El programa debe reservar los recursos a compartir. Des
pués
generará tantos filósofos como procesos hijos como se le halla indicado en e
l
argumento.
Como máximo se permitirán 10 procesos hijos compitiendo por los recursos p
ara
no sobrecargar el sistema.

*/

#define IZQ (i+nfil-1)%nfil /* Vecinos izquierdos de i */


#define DER (i+1)%nfil /* Vecinos derechos de i */

#define PENSANDO 0
#define HAMBRE 1
#define COMIENDO 2

int nfil=5; /* Número de filósofos */


int shmid, /* Identificador de la memoria compartida */
semid; /* Identificador de los semaforos */
int *estado; /* Array para ver el estado de cada filósofo */

void sintaxis(void)
{
printf("Uso: filosofo <número>\n");
return;
}

void muestra_estados(void)
{
struct sembuf op;
int i;

op.sem_num=0;
op.sem_op=-1;
op.sem_flg=0;
semop(semid, &op, 1); /* down(&mutex); */

for(i=0;i<nfil;i++)
printf("F0:%d ",estado[i]);

printf("\n");
op.sem_num=0;
op.sem_op=+1;
op.sem_flg=0;
semop(semid, &op, 1); /* up(&mutex); */
}

void probar(int i)
{
struct sembuf op;

if(estado[i] == HAMBRE && estado[IZQ]!=COMIENDO && estado[DER]!=COMIENDO)


{
estado[i]=COMIENDO;

op.sem_num=i+1;
op.sem_op=1;
op.sem_flg=0;
semop(semid, &op, 1); /* up(&s[i]); */
}
}

void tomar_palillos(int i)
{
struct sembuf op;

op.sem_num=0;
op.sem_op=-1;
op.sem_flg=0;
semop(semid, &op, 1); /* down(&mutex); */

estado[i]=HAMBRE;
probar(i);

op.sem_num=0;
op.sem_op=+1;
op.sem_flg=0;
semop(semid, &op, 1); /* up(&mutex); */

op.sem_num=i+1;
op.sem_op=-1;
op.sem_flg=0;
semop(semid, &op, 1); /* down(&s[i]); */

void dejar_palillos(int i)
{
struct sembuf op;

op.sem_num=0;
op.sem_op=-1;
op.sem_flg=0;
semop(semid, &op, 1); /* down(&mutex); */

estado[i]=PENSANDO;
probar(IZQ);
probar(DER);

op.sem_num=0;
op.sem_op=+1;
op.sem_flg=0;
semop(semid, &op, 1); /* up(&mutex); */
}

void pensar(void)
{
muestra_estados();
sleep(1); /* Estan pensando un segundo */
}

void comer(void)
{
/* muestro el nuevo estado de todos */
muestra_estados();
sleep(1); /* Estan comiendo un segundo */
}

int main(int argc, char *argv[])


{
int i,a;
struct sembuf op;

if(argc!=2)
{
sintaxis();
exit(0);
}

nfil=atoi(argv[1]);
if(nfil<2 | nfil>10)
{
printf("Parámetro incorrecto\n");
printf("El número de filósofos debe estar entre 2 y 10\n");
sintaxis();
exit(0);
}

/* Primero reservamos los recursos */

/* Reservamos un arreglo compartido para ver el estado de cada uno


este arreglo sustituye a la declaración int estado[N] de Tanenbaum
*/

shmid=shmget(IPC_PRIVATE,nfil*sizeof(int), IPC_CREAT | 0600);


if(shmid==-1)
{
perror("No pude reservar memoria compartida.\n");
exit(0);
}

/* Ahora reservamos un semáforo para cada filósofo y uno más para la exclu
sión
mutua. Este último es siempre el semáforo número cero.
*/

semid=semget(IPC_PRIVATE, nfil+1, IPC_CREAT | 0600);


if(semid==-1)
{
perror("No pude reservar los semaforos.\n");
exit(0);
}

/* Ponemos el mutex a uno */

op.sem_num=0;
op.sem_op=1;
op.sem_flg=0;
semop(semid, &op, 1); /* down(&mutex); */

/* Se crean nfil hijos */


for(i=0;i<nfil;i++)
{
a=fork();
switch(a)
{
case 0: /* Filósofo */
/* Es necesario que usemos la memoria compartida */
estado=(int *)shmat(shmid, 0, 0);
while(1) /* A este habrá que matarlo a mano con $killall filosofo *
/
{
pensar(); /* Según se crea que piense un rato */
tomar_palillos(i);
comer();
dejar_palillos(i);
}
break;
default: /* Creador de filósofos */
break;
}
}

También podría gustarte