Laboratorio 3

Neste laboratorio a tarefa foi implementar o problema do barbeiro dorminhoco utilizando threads e sincronizacao no Linux.
O problema consiste em uma certa quantidade de clientes e um barbeiro. Na barbearia existem uma determinada quantidade de cadeiras para os clietnes aguardarem. Se nao ha espaco para espera o cliente nao entra na barbearia. Se entrar na barbearia e o barbeiro estiver dormindo entao acorda o barbeiro e tem seu cabelo cortado, se o barbeiro estiver trabalhando aguarda na espera.

Apresento abaixo o codigo da solucao

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
 
//globais
int n_cadeiras;        //numero de cadeiras
int n_clientes;        //numero de clientes
sem_t s_clientes;    //semaforo para os clientes
sem_t s_barbeiro;    //semaforo para o barbeiro
sem_t mutex;        //    semaforo para a regiao de exclusao mutua
int esperando = 0;    //numero de clientes esperando para cortar o cabelo
 
//funcoes de manipulacao dos semaforos
void down(sem_t* semaphore)
{
    sem_wait(semaphore);    
}
 
void up(sem_t* semaphore)
{
    sem_post(semaphore);    
}
 
void* barbeiro(void* arg)
{
    while(1)
    {
        printf("Barbeiro: Dormindo\n");
        down(&s_clientes);
        down(&mutex);
        esperando--;
        up(&s_barbeiro);
        up(&mutex);
        printf("Barbeiro: Trabalhando\n");
        sleep(2);        
    }
}
 
void* cliente(void* arg)
{
    //salva index na variavel local
    int index = *((int*)arg);
    free(arg);
    while(1)
    {
        //espera algum tempo para tentar entrar
        sleep(random() % 10);        
        down(&mutex);
        if (esperando < n_cadeiras)
        {
            printf("Cliente: %d Entrou na barbearia\n", index);
            esperando++;
            up(&s_clientes);
            up(&mutex);
            down(&s_barbeiro);
            printf("Cliente: %d Cabelo cortado\n", index);
            //espera um tempo para o cabelo crescer de volta
            sleep(random() % 20);
            printf("Cliente: %d Cabelo grande\n", index);            
        }
        else
        {
            up(&mutex);
            printf("Cliente: %d Nao conseguiu entrar na barbearia\n", index);
        }
    }
}
 
int main()
{
    int i;
    int* index;
    void* thread_ret;
    pthread_t* threads;    
    pthread_t thread_b;
    printf("Numero de clientes: ");
    scanf("%d", &n_clientes);
    printf("Numero de cadeiras: ");
    scanf("%d", &n_cadeiras);
    //inicia semaforos
    if (sem_init(&s_barbeiro, 0, 0) != 0)
    {
        printf("Erro ao iniciar semaforo para o barbeiro\nSaindo...\n");
        return -1;
    }
    if (sem_init(&s_clientes, 0, 0) != 0)
    {
        printf("Erro ao iniciar semaforo para os clientes\nSaindo...\n");
        return -1;
    }
    if (sem_init(&mutex, 0, 1) != 0)
    {
        printf("Erro ao iniciar semaforo para o mutex\nSaindo...\n");
        return -1;
    }
    //aloca memoria para os identificadores das threads dos clientes
    if ((threads = malloc(sizeof(pthread_t) * n_clientes)) == 0)
    {
        printf("Erro ao alocar memoria para os identificadores das threads\nSaindo...\n");
        return -1;
    }
    //cria uma thread para o barbeiro
    if (pthread_create(&thread_b, 0, barbeiro, 0) != 0)
    {
        printf("Erro ao criar thread para o barbeiro\nSaindo...\n");
        return -1;
    }
    //cria uma thread para cada cliente
    for (i = 0; i < n_clientes; i++)
    {
        //aloca memoria para passar o identificador do cliente
        index = malloc(sizeof(int));
        *index = i;
        if (pthread_create(&threads[i], 0, cliente, index) != 0)
        {
            printf("Erro ao criar thread para cliente\nSaindo...\n");
            return -1;
        }            
    }
    //espera pelas threads
    if (pthread_join(thread_b, &thread_ret) != 0)
    {
        printf("Erro ao executar join com thread do barbeiro\nSaindo ...\n");
        return -1;
    }
    for (i = 0; i < n_clientes; i++)
    {
        if (pthread_join(threads[i], &thread_ret) != 0)
        {
            printf("Erro ao executar join com thread\nSaindo ...\n");
            return -1;
        }
    }
    //libera memoria alocada
    free(threads);
    return 0;
}

Apresento abaixo a tela de execucao do programa

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