Jantar dos Filosofos

INTRODUÇÃO

O problema do jantar dos filósofos foi formulado e resolvido por Dijkstra em 1959.
Cinco filósofos estão sentado em torno de uma mesa circular. Cada filósofo tem um prato de espaguete. O espaguete está tão escorregadio que um filósofo precisa de dois garfos para comê-lo. Entre cada par de pratos está o garfo.
A vida do filósofo consiste em alternar períodos de comer e pensar. Quando um filósofo fica com fome, ele tenta pegar os garfos à sua direita e à sua esquerda, um de cada vez, em qualquer ordem. Se conseguir pegar dois garfos ele comerá durante um determinado tempo e então colocará os garfos na mesa novamente e continuará a pensar.

IMPLEMENTAÇÃO

Para implementar o problema do jantar dos filósofos utilizou-se threads.

/* ***********************************************************
Implementação da solução do problema jantar dos filósofos
utilizando threads
 
O programa termina quando entrar com um caracatere
 
Tiago Porto, Maio 2009
 
*********************************************************** */
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
 
#define N 5
#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
#define TRUE 1
#define FALSE 0
 
void *thread_function(void *arg);
void *filosopher(void *i);
void take_forks(int i);
void test(int i);
void think(int i);
void eat(int i);
void put_forks(int i);
 
sem_t mutex, s[N];
 
int state[N];
 
main(){
    int res1, i;
    pthread_t a_thread[N];
    void *thread_reasult;
 
    /* Inicia o mutex */
    res1=sem_init(&mutex, 0, 1);
 
    if(res1!=0){
        perror("Falha na inicializacao do semaforo");
        exit(1);
    }
    /* Inicia os semáforos dos filósofos */
    for (i=0; i<N; i++){
        res1=sem_init(&s[i],0,0);
        if(res1!=0){
            perror("Falha na inicializacao do semaforo");
            exit(1);
        }
    }
    /* Cria os filósofos */
    printf("Criando os filosofos\n");
    for(i=0; i<N; i++){
        res1 = pthread_create(&a_thread[i], NULL, filosopher, (void *)i);
        if(res1!=0){
            perror("Falha na inicializacao dos filosofos");
            exit(1);
        }
    }
    /* Espera um caractere para sair */
    getchar();
}
/* Função do filósofo */
void *filosopher(void *i){
    int j;
    j = (int) i;
    state[j]=THINKING;
    printf("Filosofo %d iniciado\n", j);
    /* A vida do filósofo */
    while(TRUE){
        think(j);
        take_forks(j);
        eat(j);
        put_forks(j);
    }
}
/* Função que tenta pegar os garfos */
void take_forks(int i){
    sem_wait(&mutex);
    state[i] = HUNGRY;
    printf("Filosofo %d está faminto\n", i);
    test(i);
    usleep(rand()%2000000);
    sem_post(&mutex);
    sem_wait(&s[i]);
    printf("Filosofo %d pegou o garfo\n", i);
    usleep(rand()%1000000);
}
/* Função que larga os garfos */
void put_forks(int i){
    sem_wait(&mutex);
    state[i] = THINKING;
    printf("Filosofo %d largou os garfos...\n",i);
    sleep(1);
    test(LEFT);
    test(RIGHT);
    sem_post(&mutex);
}    
/* Função que testa os garfo */
void test(int i){
    if(state[i] == HUNGRY && state[LEFT]!=EATING && state[RIGHT]!=EATING){
        state[i]=EATING;
        sem_post(&s[i]);
    }
}
/* Função que representa o filósofo pensando */
void think(int i){
    printf("Filosofo %d está pensando...\n", i);
    usleep(rand()%2000000);
}    
/* Função que representa o filósofo comendo */
void eat(int i){
    printf("Filosofo %d está comendo...\n", i);
    usleep(rand()%4000000);
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License