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*)’