Outro problema clássico de CIP consistem em uma barbearia com um barbeiro, um série de cadeiras e clientes. Os pontos abaixo definem o problema:
- Cada vez que o barbeiro termina de cortar um cabelo e não existe clientes esperando, ele adormece.
- Cada vez que um cliente chega à barbearia e vê que nem uma cadeira está vazia ele não entra na barbearia e vai embora
- Quando um consumidor que está sentado na cadeira esperando vê que o barbeiro terminou de cortar um cabelo, ele tenta ser o próximo a ter o cabelo cortado.
A problemática consiste em programar consumidores e barbeio evitando condições de corrida.
A solução aplicada utiliza-se de três semáforos:
clientes - conta o número de clientes;
barbeiros - conta o número de barbeiros disponíveis.
mutex - para realizar exclusão múltipla para acesso da variável que define o número de clientes esperando;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#define CADEIRAS 5               //numero de cadeiras
     
sem_t clientes;       //semaforo para numero de clientes
sem_t barbeiros;         //semaforo para numero de barbeiros
sem_t mutex;           //mutex para acesso à numero de clientes esperando
int n_espera = 0;   //numero de clientes esperando
pthread_t t_barbeiro; //thread para o barbeiro
int n_cortados = 0;  // numero de cabelos cortados
void cabelo_cortado(int i_con);
void cortar_cabelo();
void *barbeiro ();
void *consumidor (void *i_cons);
main()
{
 
 int res; //variáveis para controle de loop e validação da criação de threads e semaforos
 int j;
 
 //criação do semáforo mutex
 res = sem_init(&mutex, 0, 1);
 if (res!= 0 ){
  perror("\nFalha na criacao de mutex");
  exit(EXIT_FAILURE); 
 }
 
 //criação do semáfor de clientes
 res = sem_init(&clientes, 0, 0);
 if (res!= 0 ){
  perror("\nFalha na criacao do semaforo de clientes");
  exit(EXIT_FAILURE); 
 } 
 
 //Iniciação da semáforo de barbeiro
 res = sem_init(&barbeiros, 0, 0);
 if (res!= 0 ){
  perror("\nFalha no semaforo de barbeiros");
  exit(EXIT_FAILURE); 
 }
 
 //Criação da thread do barbeiro  
 res = pthread_create(&t_barbeiro, NULL, barbeiro, (void *)&j);   
 if (res!= 0 ){
  perror("\nFalha na criacao da thread de barbeiro");
  exit(EXIT_FAILURE); 
 }
   
 int n = 20;// numero de clientes  
 void *resultado_thread[n];
 void *resultado_thread_barbeiro;
 pthread_t t[n]; //vetor das threads 
 int aux[n];
 
 //criação das threads
 for (j = 0 ; j<n; j++)
 {
  aux[j] = j;
  sleep(2.f);  //intervalo entre a chegada de consumdores  
  res = pthread_create(&t[aux[j]], NULL, consumidor, (void *)&aux[j]); 
  if (res!= 0 ){
  perror("\nFalha na criacao da thread");
  exit(EXIT_FAILURE); 
  }
   
 
 }
  
 //join na thread do barbeiro
 res = pthread_join(t_barbeiro, &resultado_thread_barbeiro);    
 if (res!= 0 ){
  perror("\nFalha no thread join");
  exit(EXIT_FAILURE);
   
 }
 
 //join nas threads de clientes
 for (j = 0 ; j<n; j++)
 {  
  res = pthread_join(t[j], &resultado_thread[j] );    
  if (res!= 0 )
  {
  perror("\nFalha no thread join do consumidor" );
  exit(EXIT_FAILURE);
  }  
 }  
 return 0; 
}
//função da thread do barbeiro
void *barbeiro()
{
 
   while (1) {
       sem_wait(&clientes);      //dorme se clientes for 0
        sem_wait(&mutex);          // pega acesso ao numero de clientes esperando
        n_espera = n_espera +(-1);  //decrementa clientes
        sem_post(&barbeiros);          // o barbeiro está livre
        sem_post(&mutex);            //libera o acesso ao numero de clientes esperando
        cortar_cabelo();            //corta o cabelo     
    }
   pthread_exit("exit from thread");
}
void *consumidor(void *i_con)
{
 int i = *(int *)i_con;
   sem_wait(&mutex);              //pega acesso exclusivo ào numero de clientes esperando
    if (n_espera < CADEIRAS) {    //verifica se tem cadeiras vagas
        n_espera = n_espera + 1; //entra e incrementa numero de clientes esperando       
        printf("\nConsumidor %d entra na barbearia", i);
       sem_post(&clientes);        //acorda barbeiro se necessário
        sem_post(&mutex);            //libera acesso exclusivo à numero de clientes esperando
        sem_wait(&barbeiros);        //dorme se o barbeiro não está disponivel
        cabelo_cortado(i);         //se levanta e corta o cabelo
    } else {
    printf("\nConsumidor %d viu que estava cheiro e foi embora", i);
       sem_post(&mutex);            //se não possui espaço vai embroa
    }
   pthread_exit("exit from thread");
}
void cabelo_cortado(int i_con){
 printf("\nConsumidor %d foi cortar o cabelo", i_con); 
}
void cortar_cabelo(){ 
 n_cortados++;
  sleep(3.f);
 printf("\nBarbeiro terminou corte de cabelo n %d", n_cortados);
}
No primeiro teste realizado, foram produzidos 20 clientes com intervalo de 2 s entre eles e o corte durando 3 s, assim a maior parte deles teve o cabelo cortado. O resultado abaixo confirma o esperado.
Consumidor 0 entra na barbearia
Consumidor 0 foi cortar o cabelo
Consumidor 1 entra na barbearia
Barbeiro terminou corte de cabelo n 1
Consumidor 1 foi cortar o cabelo
Consumidor 2 entra na barbearia
Barbeiro terminou corte de cabelo n 2
Consumidor 2 foi cortar o cabelo
Consumidor 3 entra na barbearia
Consumidor 4 entra na barbearia
Barbeiro terminou corte de cabelo n 3
Consumidor 3 foi cortar o cabelo
Consumidor 5 entra na barbearia
Barbeiro terminou corte de cabelo n 4
Consumidor 4 foi cortar o cabelo
Consumidor 6 entra na barbearia
Consumidor 7 entra na barbearia
Barbeiro terminou corte de cabelo n 5
Consumidor 5 foi cortar o cabelo
Consumidor 8 entra na barbearia
Barbeiro terminou corte de cabelo n 6
Consumidor 6 foi cortar o cabelo
Consumidor 9 entra na barbearia
Consumidor 10 entra na barbearia
Barbeiro terminou corte de cabelo n 7
Consumidor 7 foi cortar o cabelo
Consumidor 11 entra na barbearia
Barbeiro terminou corte de cabelo n 8
Consumidor 8 foi cortar o cabelo
Consumidor 12 entra na barbearia
Consumidor 13 entra na barbearia
Barbeiro terminou corte de cabelo n 9
Consumidor 9 foi cortar o cabelo
Consumidor 14 entra na barbearia
Barbeiro terminou corte de cabelo n 10
Consumidor 10 foi cortar o cabelo
Consumidor 15 entra na barbearia
Consumidor 16 viu que estava cheiro e foi embora
Barbeiro terminou corte de cabelo n 11
Consumidor 11 foi cortar o cabelo
Consumidor 17 entra na barbearia
Barbeiro terminou corte de cabelo n 12
Consumidor 12 foi cortar o cabelo
Consumidor 18 entra na barbearia
Consumidor 19 viu que estava cheiro e foi embora
Barbeiro terminou corte de cabelo n 13
Consumidor 13 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 14
Consumidor 14 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 15
Consumidor 15 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 16
Consumidor 17 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 17
Consumidor 18 foi cortar o cabelo
O segundo teste foi feito produzindo-se todos os clientes sem intervalo. O esperado é que o primeiro cliente entre na barbearia e tenha logo seu cabelo, os próximos cinco entram ficam esperando até cortar o cabelo e os demais chegam à barbearia mas vão embora quando vêem que não tem cadeira vazia. O resultado abaixo confirma o esperado:
Consumidor 0 entra na barbearia
Consumidor 0 foi cortar o cabelo
Consumidor 1 entra na barbearia
Consumidor 2 entra na barbearia
Consumidor 3 entra na barbearia
Consumidor 4 entra na barbearia
Consumidor 5 entra na barbearia
Consumidor 6 viu que estava cheiro e foi embora
Consumidor 7 viu que estava cheiro e foi embora
Consumidor 8 viu que estava cheiro e foi embora
Consumidor 9 viu que estava cheiro e foi embora
Consumidor 10 viu que estava cheiro e foi embora
Consumidor 11 viu que estava cheiro e foi embora
Consumidor 12 viu que estava cheiro e foi embora
Consumidor 13 viu que estava cheiro e foi embora
Consumidor 14 viu que estava cheiro e foi embora
Consumidor 15 viu que estava cheiro e foi embora
Consumidor 16 viu que estava cheiro e foi embora
Consumidor 17 viu que estava cheiro e foi embora
Consumidor 18 viu que estava cheiro e foi embora
Consumidor 19 viu que estava cheiro e foi embora
Barbeiro terminou corte de cabelo n 1
Consumidor 1 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 2
Consumidor 2 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 3
Consumidor 3 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 4
Consumidor 4 foi cortar o cabelo
Barbeiro terminou corte de cabelo n 5
Consumidor 5 foi cortar o cabelo
quinta-feira, 7 de maio de 2009
Assinar:
Postar comentários (Atom)
Gostaria de saber o porque de ta dando esse erro:
ResponderExcluirerror: invalid conversion from ‘void* (*)()’ to ‘void* (*)(void*)’
error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’