Primeira Questao da Prova

A primeira questão da prova era sobre um banheiro com três estados: VAZIO, COM HOMEM e COM MULHER. Uma pessoa de um determinado sexo só poderia utilizar o banheiro se este estivesse VAZIO ou com o estado do sexo correspondente. Como fazer isso sem condições de disputa?

Foi implementada uma solução usando semáforos para as funções homem_quer_entrar, homem_quer_sair, mulher_quer_entrar e mulher_quer_sair para evitar condições de disputa.

O código do programa implementado pode ser visto abaixo.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
 
#define HOMENS 18
 
#define MULHERES 20
 
#define VAZIO 0
 
#define COM_HOMEM 1
 
#define COM_MULHER 2
 
sem_t mutex;
 
int i, estado, homens, mulheres, int_rand;
 
float randomic;
 
homens=0;
 
mulheres=0;
 
void *homem(void *j){
 
   int i=*(int*)j;
 
   while (1){
 
   int entrou=0;
 
   int saiu=0;
 
   while(entrou==0){
 
      entrou=homem_quer_entrar(i);
 
      randomic=0.00001*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   }
 
         randomic=0.00001*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   while(saiu==0){
 
      saiu=homem_quer_sair(i);
 
            randomic=0.01*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   }
   }
 
}
 
void *mulher(void *j){
 
   int i=*(int*)j;
   while(1){
 
   int entrou=0;
 
   int saiu=0;
 
   while(entrou==0){
 
      entrou=mulher_quer_entrar();
 
      randomic=0.00001*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   }
 
      randomic=0.00001*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   while(saiu==0){
 
      saiu=mulher_quer_sair();
 
      randomic=0.01*random();
 
      int_rand=randomic;
 
      usleep(int_rand);
 
   }
   }
 
}
 
int homem_quer_entrar(int i){
 
   sem_wait(&mutex);
 
   int retorno=0;
 
   if(estado==VAZIO){
 
       retorno=1;
 
       homens++;
 
       estado=COM_HOMEM;
       printf("Homem %d entrou no vazio.\n",i+1);
 
   }
 
   else if(estado==COM_HOMEM){
 
       retorno=1;
 
       homens++;
       printf("Homem %d entrou no com homem.\n",i+1);
 
   }
 
   sem_post(&mutex);
   return retorno;
 
}
 
int homem_quer_sair(int i){
 
   sem_wait(&mutex);
 
      homens--;
 
      if(homens==0){
 
          estado=VAZIO;
 
      }
 
      printf("Homem %d saiu.\n",i+1);
 
   sem_post(&mutex);
   return 1;
 
}
 
int mulher_quer_entrar(int i){
 
   sem_wait(&mutex);
 
   int retorno=0;
 
   if(estado==VAZIO){
 
       retorno=1;
 
       mulheres++;
 
       estado=COM_MULHER;
       printf("Mulher %d entrou no vazio.\n",i+1);
 
   }
 
   else if(estado==COM_MULHER){
 
       retorno=1;
 
       mulheres++;
       printf("Mulher %d entrou no com mulher.\n",i+1);
 
   }
 
   sem_post(&mutex);
 
   return retorno;
 
}
 
int mulher_quer_sair(int i){
 
   sem_wait(&mutex);
 
      mulheres--;
 
      if(mulheres==0){
 
          estado=VAZIO;
 
      }
 
      printf("Mulher %d saiu.\n",i+1);
 
   sem_post(&mutex);
   return 1;
 
}    
 
void main(){
 
   estado=VAZIO;
 
   int res;
 
   void *thread_result;
 
   pthread_t thread[100];
 
   res = sem_init(&mutex,0,1);
    if(res!=0){
       perror("Erro na inicialização do semaforo!");
       exit(EXIT_FAILURE);
    }
 
   for(i=0; i<18; i++){
       res = pthread_create(&thread[i],NULL,homem,&i);
       if(res!=0){
          perror("Erro na inicialização da thread!");
          exit(EXIT_FAILURE);
       }
    }
 
   for(i=18; i<38; i++){
       res = pthread_create(&thread[i],NULL,mulher,&i);
       if(res!=0){
          perror("Erro na inicialização da thread!");
          exit(EXIT_FAILURE);
       }
    }
 
   for(i=0; i<38; i++){
       res = pthread_join(thread[i],&thread_result);
       if(res!=0){
          perror("Erro ao fazer join nas threads!");
          exit(EXIT_FAILURE);
       }
    }
 
}

O resultado da execução do programa, para 18 homens e 20 mulheres disputando o banheiro, pode ser visto abaixo.

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