Questão1 Prova1 2009

ENUNCIADO

As regras de uso de um banheiro permite que, quando uma mulher estiver no banheiro, outra mulher poderá entrar mas um homem não e vice-versa.
Um sinal na porta indica em qual dos três estados o banheiro se encontra: Vazio, Com Mulher ou Com Homem.
Escreva os seguintes procedimentos: Mulher quer entrar, Homem quer entrar, Mulher sai, Homem sai. Utilize o mecanismo de sincronização que você mais considerar mais apropriado.

IMPLEMENTAÇÃO

Para perceber melhor os resultados, considerou-se que cada homem e mulher vai 2 vezes ao banheiro.

/* ***********************************************************
Implementação da solução do problema 1 da prova 1.2009
 
Considerando que cada homem e mulher vai 2 vezes ao banheiro
 
O programa recebe 2 parametro:
 - primeiro corresponde ao número de homens
 - segundo corresponde ao número de mulheres
 
Tiago Porto, Maio 2009
 
*********************************************************** */
 
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
 
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
 
#define VAZIO 0
#define COM_HOMEM 1
#define COM_MULHER 2
#define TRUE 1
#define FALSE 0
#define MAX 100
 
void *mulher(void *arg);
int mulher_quer_entrar(int i);
void mulher_sai(int i);
void *homem(void *arg);
int homem_quer_entrar(int i);
void homem_sai(int i);
 
pthread_mutex_t mutex;  
int pessoa, banheiro;
pthread_t mulher_thread[MAX], homem_thread[MAX];
 
main (int arc, char *argv[]) { 
    int i, fd, res, n_homem, n_mulher, max_homem, max_mulher;
    /* Inicialização de variáveis */
    banheiro = VAZIO;
    pessoa = 0;
 
     max_homem = atoi(argv[1]);
     max_mulher = atoi(argv[2]);
    /* Iniciando mutex */
     if(pthread_mutex_init(&mutex, NULL)!=0){
         perror("Falha na inicializacao do semaforo");
        exit(1);
    }
    /* Criando mulheres */
     for(n_mulher = 0; n_mulher < max_mulher; n_mulher++){
         res = pthread_create(&mulher_thread[n_mulher], NULL, mulher, (void *)n_mulher);
         if (res != 0)
             exit(1);
     }
     /* Criando homens */
     for(n_homem = 0; n_homem < max_homem; n_homem++){
        res = pthread_create(&homem_thread[n_homem], NULL, homem, (void *)n_homem);
         if (res != 0)
             exit(1);
     }
     getchar();
}
/* Função da mulher */
void *mulher(void *arg){
    int i =(int) arg, j;
    usleep(rand()%2000000);
    printf("Mulher %d criada\n", i);
    for (j = 0; j< 2; j++) {
        printf("Mulher %d tentando entrar\n",i);
        while(mulher_quer_entrar(i))
            usleep(rand()%1000);
        usleep(rand()%10);
        mulher_sai(i);
        usleep(rand()%2000000);
    }
    /* Libera a thread */
    pthread_exit("");
}
/* Função que mostra o desejo da mulher de entrar no banheiro */
int mulher_quer_entrar(int i){
    pthread_mutex_lock(&mutex);
    if(banheiro==COM_MULHER || banheiro == VAZIO){    
        if(banheiro==VAZIO){
            banheiro=COM_MULHER;
        }
        printf("Mulher %d entrou\n", i);
        pessoa ++;
        pthread_mutex_unlock(&mutex);
        return FALSE;
    } else { 
        pthread_mutex_unlock(&mutex);
        return TRUE;
    }
}
/* Função da mulher saindo do banheiro*/
void mulher_sai(int i){
    pthread_mutex_lock(&mutex);
    pessoa--;
    printf("Mulher %d saiu\n", i);
    if(pessoa == 0){
        banheiro=VAZIO;
        puts("Banheiro vazio");
    }
    pthread_mutex_unlock(&mutex);
}
/* Função do homem */
void *homem(void *arg){
    int i, j;
    i=(int) arg;
    usleep(rand()%2000000);
    printf("Homem %d criado\n", i);
    for (j =0; j< 2; j++) {
        printf("Homem %d tentando entrar\n",i);
        while(homem_quer_entrar(i))
            usleep(rand()%1000);
        usleep(rand()%1000000);
        homem_sai(i);
        usleep(rand()% 20000);
    }
    /* Libera a thread */
    pthread_exit("");
}
/* Função que mostra o desejo do homem de entrar no banheiro */
int homem_quer_entrar(int i){
    pthread_mutex_lock(&mutex);
    if(banheiro==COM_HOMEM || banheiro ==VAZIO){
        if(banheiro==VAZIO)
            banheiro=COM_HOMEM;
        pessoa++;
        printf("Homem %d entrou\n", i);
        pthread_mutex_unlock(&mutex);
        return FALSE;
    } else {
        pthread_mutex_unlock(&mutex);
        return TRUE;
    }
}
/* Função do homeme saindo do banheiro */
void homem_sai(int i){
    pthread_mutex_lock(&mutex);
    pessoa--;
    printf("Homem %d saiu\n", i);    
    if(pessoa == 0){
        banheiro=VAZIO;
        puts("Banheiro vazio");
    }
    pthread_mutex_unlock(&mutex);
}

TESTES

Teste 1: 1 homem e 1 mulher
Teste 2: 2 homens e 3 mulheres
Teste 3: 3 homens e 2 mulheres

$ ./ex1 1 1
Mulher 0 criada
Mulher 0 tentando entrar
Mulher 0 entrou
Mulher 0 saiu
Banheiro vazio
Mulher 0 tentando entrar
Mulher 0 entrou
Mulher 0 saiu
Banheiro vazio
Homem 0 criado
Homem 0 tentando entrar
Homem 0 entrou
Homem 0 saiu
Banheiro vazio
Homem 0 tentando entrar
Homem 0 entrou
Homem 0 saiu
Banheiro vazio

$ ./ex1 2 3
Mulher 0 criada
Mulher 0 tentando entrar
Mulher 0 entrou
Mulher 0 saiu
Banheiro vazio
Homem 0 criado
Homem 0 tentando entrar
Homem 0 entrou
Mulher 1 criada
Mulher 1 tentando entrar
Homem 0 saiu
Banheiro vazio
Mulher 1 entrou
Mulher 1 saiu
Banheiro vazio
Homem 0 tentando entrar
Homem 0 entrou
Mulher 2 criada
Mulher 2 tentando entrar
Homem 1 criado
Homem 1 tentando entrar
Homem 1 entrou
Homem 1 saiu
Homem 1 tentando entrar
Homem 1 entrou
Homem 0 saiu
Mulher 0 tentando entrar
Mulher 1 tentando entrar
Homem 1 saiu
Banheiro vazio
Mulher 1 entrou
Mulher 1 saiu
Banheiro vazio
Mulher 2 entrou
Mulher 0 entrou
Mulher 0 saiu
Mulher 2 saiu
Banheiro vazio
Mulher 2 tentando entrar
Mulher 2 entrou
Mulher 2 saiu
Banheiro vazio

$ ./ex1 3 2
Mulher 0 criada
Mulher 0 tentando entrar
Mulher 0 entrou
Mulher 0 saiu
Banheiro vazio
Homem 1 criado
Homem 1 tentando entrar
Homem 1 entrou
Mulher 1 criada
Mulher 1 tentando entrar
Homem 1 saiu
Banheiro vazio
Mulher 1 entrou
Mulher 1 saiu
Banheiro vazio
Homem 1 tentando entrar
Homem 1 entrou
Homem 0 criado
Homem 0 tentando entrar
Homem 0 entrou
Homem 2 criado
Homem 2 tentando entrar
Homem 2 entrou
Homem 1 saiu
Mulher 0 tentando entrar
Mulher 1 tentando entrar
Homem 0 saiu
Homem 0 tentando entrar
Homem 0 entrou
Homem 2 saiu
Homem 2 tentando entrar
Homem 2 entrou
Homem 2 saiu
Homem 0 saiu
Banheiro vazio
Mulher 0 entrou
Mulher 0 saiu
Banheiro vazio
Mulher 1 entrou
Mulher 1 saiu
Banheiro vazio
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License