martes, 4 de octubre de 2011

PROGRAMA EXAMEN

 

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 información
        printf("Estado de los filósofos: \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;
}

No hay comentarios:

Publicar un comentario