quinta-feira, 7 de maio de 2009

A barbearia

A barbearia na "vida" computacional possui um barbeiro dorminhoco, uma cadeira para o barbeiro cortar o cabelo do cliente e algumas cadeiras de espera. Se um cliente adentra a barbearia e o barbeiro está dormindo, ele é acordado e o cliente, atendido. Caso contrário o cliente senta em uma das cadeiras de espera. Se não há cadeiras de espera livres, o cliente simplesmente vai embora. Quando o barbeiro termina o corte de um cliente, dá uma olhada nas cadeiras de espera, se houver clientes, ele escolhe um e o atende. Caso contrário, volta a dormir até aparecerem novos clientes.

Para garantir que clientes não furem fila, que o barbeiro não durma para sempre, que os clientes em espera sejam atendidos e apenas um por vez são usados semáforos.

O código a seguir implementa a barbearia da vida computacional.

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

#define CHAIRS 5
#define TRUE 1
#define FALSE 0
#define T_BARB 3
#define T_CUST 1

sem_t customers;
sem_t barbers;
sem_t mutex;

int
waiting = 0;

void
*barbeiro_thread(void *arg);
void
*cliente_thread(void *arg);


void
barber_sleeping(){
printf("Barbeiro dormindo...\n");
}


void
cut_hair(){
printf("Barbeiro ocupado...\n");
}


void
customers_waiting(int i){
printf("Clientes aguardando: %i\n",i);
}


void
customer_leaves(){
printf("Cliente vai embora...\n");
}


void
get_haircut(){
printf("Cliente tem o cabelo aparado...\n");
}



void
barber(void){

while
(TRUE) {
barber_sleeping();
sem_wait(&customers);
sem_wait(&mutex);
waiting = waiting - 1;
sem_post(&barbers);
sem_post(&mutex);
cut_hair();
sleep(T_BARB);
}
}



void
customer(void){

sem_wait(&mutex);

if
(waiting < CHAIRS) {

waiting = waiting + 1;
sem_post(&customers);
sem_post(&mutex);
customers_waiting(waiting);
sem_wait(&barbers);
get_haircut();
}
else {
customer_leaves();
sem_post(&mutex);
}
}



void
*barbeiro_thread(void *arg){
barber();
}



void
*ccliente_thread(void *arg){
customer();
}



void
*cliente_thread(void *arg){
pthread_t cc_thread;

while
(1){
sleep(T_CUST);
pthread_create(&cc_thread,NULL,ccliente_thread,NULL);
}
}


int
main(){
pthread_t b_thread;
pthread_t c_thread;

sem_init(&customers,0,0);
sem_init(&barbers,0,0);
sem_init(&mutex,0,1);

pthread_create(&b_thread,NULL,barbeiro_thread,NULL);
pthread_create(&c_thread,NULL,cliente_thread,NULL);

pthread_join(b_thread,NULL);
pthread_join(c_thread,NULL);

return
0;
}

O semáforo barbers serve para sinalizar se o barbeiro está ou não ocupado e garante que os clientes não furem fila. O semáforo customers serve para sinalizar se há clientes. O semáforo mutex garante o atendimento de apenas um cliente por vez e que todos em espera serão atendidos. O barbeiro e os clientes são threads.

Façamos a simulação de um barbeiro preguiçoso, que demora para atender os clientes, sendo que os clientes estão chegando rapidamente à barbearia. Temos o seguinte resultado:



Percebe-se que as cadeiras de espera enchem rapidamente e vários clientes vão embora.

Agora, façamos a simulação de um barbeiro eficiente, que atende rapidamente os clientes. Temos o seguinte resultado:



Percebe-se que há, no máximo, um cliente na cadeira de espera.

Nenhum comentário:

Postar um comentário

Seguidores