Quando um consumidor chega a barbearia, ele acorda o barbeiro para obter o corte de cabelo, ou senta-se nas cadeiras para esperar se o barbeiro estiver cortando o cabelo de outra pessoa. Caso todas as cadeiras da barbearia estejam ocupadas, o consumidor simplesmente deixa o local.
Este problema é interessante, pois devemos coordenar as atividades sem gerar condições de corrida. Uma solução falha pode resultar em problemas de starvation ou de deadlock entre os processos.
O deadlock é obtido quando o consumidor fica esperando o barbeiro e o barbeiro fica esperando o consumidor.
A situação de starvation é obtida quando os consumidores não possuem uma ordem para o corte de cabelo, assim pode haver a situação em que consumidores não obtem a chance de ter seu cabelo cortado, esperando para sempre.
Em nossa solução, vamos considerar um barbeiro e vários consumidores, chegando em intervalos de tempo randômicos. O barbeiro será uma thread e cada consumidor será outra thread. Teremos semáforos para garantir que situações de deadlock não ocorram. Além disso, consideramos que o tempo para o corte de cabelo será constante para todos os consumidores. Isto pode ser alterado!
Utilizaremos as instruções sem_wait e sem_post para controlar o acesso às regiões críticas. Documentação do uso pode ser encontrada em:
http://www.opengroup.org/onlinepubs/007908775/xsh/sem_wait.html
http://www.opengroup.org/onlinepubs/007908799/xsh/sem_post.html
Para criar estes semáforos, vamos utilizar os seguintes comandos sem_t e sem_init:
http://www.opengroup.org/onlinepubs/007908775/xsh/sem_init.html
Além disso, devemos criar as threads. Isto pode ser feito utilizando os seguintes comandos:
declaração: pthread_t
criação: pthread_create() - http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_create.html
Aqui, é interessante notar que ao criarmos a thread, ela inicia sua execução. Contudo, a thread principal não pára sua execução! Assim, é necessário utilizarmos o comando pthread_join para evitar que a thread principal termine o programa, e com isso, mate todas as outras threads.
pthread_join() - http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_join.html
Para aprender mais sobre este problema, visite: http://en.wikipedia.org/wiki/Sleeping_barber_problem
Utilizando o seguinte comando:
gcc [[nome_programa.c]] -o [[nome_programa]] -lpthread
compilamos o programa e geramos o arquivo executável.
Para executar o programa, utilizamos o seguinte comando:
./[[nome_programa]]
Utilizamos o seguinte código:
//Bibliotecas utilizadas...
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define CHAIRS 5 //quantidade de cadeiras na barbearia
#define CONSUMERS 100000 //quantidade total de clientes
/*
typedef int semaphore; /*os semaforos sao um tipo especial de int
semaphore customers=0; /*array para controlar o estado de todos
semaphore barbers=0;
semaphore mutex = 1; /*exclusão mutua para regioes criticas
semaphore s[N]; /*um semaforo por filosofo
*/
sem_t customers; //semaforo para controlar os consumidores esperando pelo corte de cabel
sem_t barbers; //semaforo para controlar os barbeiros esperando pelos consumidores
sem_t mutex; //semaforo para exclusao mutua para regioes criticas
int waiting=0;
//prototipos...
void cut_hair();
void get_haircut();
void barber()
{
while(1)
{
if(waiting==0) printf("Barber esperando consumidores... \n"); //caso a quantidade de pessoas na barbearia seja 0
sem_wait(&customers); //down(&customers); dorme se a quantidade de consumidores for 0
sem_wait(&mutex); //down(&mutex); garante acesso exclusivo a variavel waiting
waiting=waiting-1; //diminui a quantidade de clientes esperando
sem_post(&barbers); //up(&barbers); um barbeiro esta pronto para realizar o corte de cabelo
sem_post(&mutex); //up(&mutex); libera o acesso a variavel waiting
cut_hair(); //corta o cabelo do cliente
}
}
void customer()
{
sem_wait(&mutex); //down(&mutex); garante acesso exclusivo a variavel waiting
if(waiting<CHAIRS) //se nao houver cadeiras livres, vai embora...
{
waiting = waiting + 1; //aumenta a quantidade de clientes esperando
printf("Mais um consumidor! Total de %d consumidores esperando\n",waiting);
sem_post(&customers); //up(&customers);acorda o barbeiro avisando que temos um novo cliente
sem_post(&mutex); //up(&mutex); libera o acesso a variavel waiting
sem_wait(&barbers); //down(&barbers); espera se todos os barbeiros estiverem ocupados
get_haircut(); //obtem corte de cabelo...
}
else
{
printf("Cadeiras lotadas... vou embora\n");
sem_post(&mutex);
}
}
void cut_hair()
{
/*Barbeiro esta cortando cabelo*/
printf("Barber is cutting hair\n");
sleep(3);
return;
}
void get_haircut()
{
/*Cliente esta recebendo corte de cabelo*/
sleep(3);
return;
}
main()
{
pthread_t barberthread, consumerthread[CONSUMERS];
int i=0,sleeptime;
// Create independent threads each of which will execute function
/*To initialize a semaphore, use sem_init():
int sem_init(sem_t *sem, int pshared, unsigned int value);
sem_init(&sem_name, 0, 10);
*/
sem_init(&customers, 0, 0);
sem_init(&barbers, 0, 1);
sem_init(&mutex, 0, 1);
pthread_create( &barberthread, NULL,(void *) barber, NULL );
for(i=0;i<CONSUMERS;i++)
{
sleeptime = rand()%5;
sleep(sleeptime);
pthread_create(&consumerthread[i], NULL, (void *) customer, NULL);
}
pthread_join( barberthread, NULL);
for(i=0;i<CONSUMERS;i++){
pthread_join( consumerthread[i], NULL);
}
exit(0);
}
Assim, obtivemos o seguinte resultado:
andersonaiziro@Aaiziro:~/Documents$ ./sleepbarber
Barber esperando consumidores...
Mais um consumidor! Total de 1 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 1 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 1 consumidores esperando
Mais um consumidor! Total de 2 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 2 consumidores esperando
Mais um consumidor! Total de 3 consumidores esperando
Mais um consumidor! Total de 4 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 4 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 4 consumidores esperando
Mais um consumidor! Total de 5 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Cadeiras lotadas... vou embora
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Cadeiras lotadas... vou embora
Cadeiras lotadas... vou embora
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Cadeiras lotadas... vou embora
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Cadeiras lotadas... vou embora
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Barber is cutting hair
Mais um consumidor! Total de 5 consumidores esperando
Barber is cutting hair
Nenhum comentário:
Postar um comentário