CODIGO
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define NUM_FILOSOFOS 5
#define PENSANDO 0
#define COMIENDO 1
#define LIBRE 1
#define USADO 0
typedef struct datos_filosofos {
int filosofos[NUM_FILOSOFOS];
int pids[NUM_FILOSOFOS];
int semaforo_id,semaforo_id2;
int memoria_id;
} datos_filosofos;
struct datos_filosofos *p_filosofos;
// Reservar semáforos y memoria compartida
int crea_filosofos(void)
{
int i;
int sem_id,sem_id2,mem_id;
// Crea el área de memoria compartida
if((mem_id=shmget(IPC_PRIVATE,sizeof(datos_filosofos),0774 | IPC_CREAT))==-1)
return -1;
if(!(p_filosofos=(datos_filosofos *)shmat(mem_id,(char *)0,0)))
return -2;
// Crea el set de semáforos para los cubiertos
if((sem_id=semget(IPC_PRIVATE,NUM_FILOSOFOS,0774 | IPC_CREAT))==-1)
return -3;
// Crea el semáforo que evitará el interbloqueo
if((sem_id2=semget(IPC_PRIVATE,1,0774 | IPC_CREAT))==-1)
return -3;
// Inicializa el área de memoria compartida
for(i=0;i<NUM_FILOSOFOS;i++)
{
p_filosofos->filosofos[i]=PENSANDO;
p_filosofos->pids[i]=0;
semctl(sem_id,i,SETVAL,LIBRE);
}
semctl(sem_id2,0,SETVAL,NUM_FILOSOFOS-1);
p_filosofos->semaforo_id=sem_id;
p_filosofos->semaforo_id2=sem_id2;
p_filosofos->memoria_id=mem_id;
return sem_id;
}
// Liberar semáforos y memoria compartida
void elimina_filosofos(void)
{
int i;
int mem_id,sem_id;
mem_id=p_filosofos->memoria_id;
shmdt((char *)p_filosofos);
shmctl(mem_id,IPC_RMID,(struct shmid_ds *)NULL);
for(i=0;i<NUM_FILOSOFOS;i++)
semctl(sem_id,i,IPC_RMID);
}
// Wait
void P(int id,int i)
{
struct sembuf op[3]={i,-1,0};
semop(id,op,1);
}
// Signal
void V(int id,int i)
{
struct sembuf op[3]={i,1,0};
semop(id,op,1);
}
int main()
{
int res;
int i;
// Crea filósofos: reservar memoria, crear semáforos
res=crea_filosofos();
if(res<0)
{
printf("Error %d\n",-res);
return 0;
}
// Crea los filósofos (procesos hijos)
for(i=0;i<NUM_FILOSOFOS;i++)
if(!fork())
{
// Proceso hijo #i
p_filosofos->pids[i]=getpid();
while(1)
{
// Máximo NUM_FILOSOFOS-1 entran a tratar de comer para evitar el interbloqueo
P(p_filosofos->semaforo_id2,0);
// Espera los dos cubiertos
P(p_filosofos->semaforo_id,i);
P(p_filosofos->semaforo_id,(i+1)%NUM_FILOSOFOS);
p_filosofos->filosofos[i]=COMIENDO;
sleep(1);
// Devuelve los dos cubiertos
V(p_filosofos->semaforo_id,i);
V(p_filosofos->semaforo_id,(i+1)%NUM_FILOSOFOS);
p_filosofos->filosofos[i]=PENSANDO;
// Deja que otro trate de comer
V(p_filosofos->semaforo_id2,0);
}
}
// Bucle de espera del proceso padre
while(res!=27)
{
// Muestra informacion
printf("Estado de los filosofos: \n");
for(i=0;i<NUM_FILOSOFOS;i++)
printf("%d[%d] ==> %d\n",i,p_filosofos->pids[i],p_filosofos->filosofos[i]);
res=getchar();
}
// Elimina los procesos hijos
for(i=0;i<NUM_FILOSOFOS;i++)
kill(p_filosofos->pids[i],9);
elimina_filosofos();
return 0;
}
AQUI SE MUESTRA LOS 3 ARCHIVOS QUE SE CREAN DESPUES DE COMPILAR Y CONSTRUIRLOS EN GEANY
AQUI SE MUESTRA COMO COMEN LOS FILOSOFOS 1 Y 4
AQUI SE MUESTRA COMO COMEN LOS FILOSOFOS 1 Y 3
AQUI SE MUESTRA COMO COMEN LOS FILOSOFOS 2 Y 4
AQUI SE MUESTRA COMO COME EL FILOSOFO 2
No hay comentarios:
Publicar un comentario