Laboratorio 2

Neste laboratorio a tarefa foi implementar o problema do jantar dos filosofos uitilizando threads no Linux.

Encapsulando as chamadas sem_wait e sem_post com as funcoes up e down, respectivamente, foi possivel implementar a solucao na forma como e apresentada na referencia da materia.

Abaixo apresento o codigo fonte da solucao do problema.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
 
#define PENSANDO 0
#define FAMINTO 1
#define COMENDO 2
 
//globais
sem_t mutex;        //semaforo para regiao de exclusao mutua
int* estado;        //vetor com os estados dos filosofos
sem_t* s;        //vetor de semaforos para os filosofos
int n_filosofos;    //numero de filosofos
char* status_str[3] = {"PENSANDO","FAMINTO","COMENDO"};
 
void imprime_status(int index, int status)
{
    printf("Filosofo %d: %s\n", index, status_str[status]);    
}
 
//funcoes de manipulacao dos semaforos
void down(sem_t* semaphore)
{
    sem_wait(semaphore);    
}
 
void up(sem_t* semaphore)
{
    sem_post(semaphore);    
}
 
void come(int index)
{
    imprime_status(index, COMENDO);
    //fica comendo por 5 segundos
    sleep(5);
}
 
void pensa(int index)
{
    int sleep_time;
    imprime_status(index, PENSANDO);
    //sorteia um valor para esperar
    sleep_time = random() % 10;
    sleep(sleep_time);
}
 
void testa(int index)
{
    if (estado[index] == FAMINTO && estado[esquerda(index)] != COMENDO && estado[direita(index)] != COMENDO)
    {
        estado[index] = COMENDO;
        up(&s[index]);
    }
}
 
void pega_garfos(int index)
{
    down(&mutex);
    estado[index] = FAMINTO;
    testa(index);
    up(&mutex);
    down(&s[index]);
}
 
void libera_garfos(int index)
{
    down(&mutex);
    estado[index] = PENSANDO;
    testa(esquerda(index));
    testa(direita(index));
    up(&mutex);
}
 
int direita(int index)
{
    return (index + 1) % n_filosofos;
}
 
int esquerda(int index)
{
    return (index + n_filosofos - 1) % n_filosofos;
}
 
void* tarefa_filosofo(void* arg)
{
    int index = *((int*)arg);
    //libera argumento, mantem apenas na variavel local
    free(arg);
    while(1)
    {
        pensa(index);
        imprime_status(index, FAMINTO);
        pega_garfos(index);
        come(index);
        libera_garfos(index);
    }
    return 0;
}
 
int main()
{
    pthread_t* threads;
    int ret, i;
    int* index;
    void* thread_ret;
    printf("Numero de filosofos: ");
    scanf("%d", &n_filosofos);
    //aloca memoria para o vetor com informacao de cada thread
    if ((threads = malloc(sizeof(pthread_t) * n_filosofos)) == 0)
    {
        printf("Erro ao alocar memoria para os identificadores das threads\nSaindo...\n");
        return -1;
    }
    //aloca memoria para vetor de estados
 
    if ((estado = malloc(sizeof(int) * n_filosofos)) == 0)
    {
        printf("Erro ao alocar memoria para os estados dos filosofos\nSaindo...\n");
        return -1;
    }
    //aloca memoria para os semaforos    
    if ((s = malloc(sizeof(sem_t) * n_filosofos)) == 0)
    {
        printf("Erro ao alocar memoria para os semaforos\nSaindo...\n");
        return -1;
    }
    //inicia semaforos
    for (i = 0; i < n_filosofos; i++)
    {
        if (sem_init(&s[i], 0, 0) != 0)
        {
            printf("Erro ao iniciar semaforo\nSaindo ...\n");
        }
    }
    //inicia mutex
    if (sem_init(&mutex, 0, 1) != 0)
    {
        printf("Erro ao iniciar mutex\nSaindo ...\n");
    }    
    //cria uma thread para cada filosofo
    for (i = 0; i < n_filosofos; i++)
    {
        //aloca memoria para enviar o index do filosofo para a thread
        //liberacao por conta da thread
        index = malloc(sizeof(int));
        *index = i;
        if (pthread_create(&threads[i], 0, tarefa_filosofo, index) != 0)
        {
            printf("Erro ao criar thread para filosofo\nSaindo...\n");
            return -1;
        }
    }    
    //aguarda pelo termino das threads
    for (i = 0; i < n_filosofos; i++)
    {
        if (pthread_join(threads[i], &thread_ret) != 0)
        {
            printf("Erro ao executar join com thread\nSaindo ...\n");
            return -1;
        }
    }
    printf("Tarefa terminanda\nSaindo ...\n");
    //libera memoria alocada
    free(threads);
    free(estado);
    free(s);
    return 0;
}

Apresento abaixo a saida do programa para 3 e 8 filosofos.

3 Filosofos

execucao_lab2_1.png

8 Filosofos

execucao_lab2_2.png
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License