#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#define Max_Clientes 25 // El número máximo de hebras clientes.
// Prototipos de funciones...
void *clientes(void *num);
void *barbero(void *);
void rango_espera(int secs);
//Se definen los semaforos.
//El curto_espera pone el limite del numero de clientes que se permiten ingresar al cuarto de espera en un tiempo determinado.
sem_t cuartoespera;
// La SillaBarbero asegura la mutua exclusividad en el acceso a la silla del barbero.
sem_t SillaBarbero;
// AlmohadaBarbero es usada para permitir que el barbero descanse hasta que llegue el cliente.
sem_t AlmohadaBarbero;
// CinturonAsiento es usada para hacer que el cliente espere hasta que el barbero haya cortado su cabello.
sem_t CinturonAsiento;
// Bandera que para la hebra del barbero cuando todos los clientes han sido atentidos.
int Todohecho = 0;
int clientesBarberia=0;
int numSillas;
int main(int argc, char *argv[])
{
int i;
pthread_t btid;
pthread_t tid[Max_Clientes];
int numClientes;
int Numero[Max_Clientes];
printf("El ńumero maximo de clientes es 25. Ingresa el numero de clientes y sillas.\n");
do{
scanf("%d",&numClientes
);
if(numClientes
> Max_Clientes
)printf("El nº de clientes debe ser menor a %d, ingrese nº de clientes y sillas nuevamente.\n",Max_Clientes
);
}while(numClientes>Max_Clientes);
if (numClientes > Max_Clientes) {
printf("El Maximo numero de Clientes es %d.\n", Max_Clientes
); /******system("PAUSE");*****************/
return 0;
}
printf("Una solucion al problema del barbero dormilon usando semaforos.\n"); for (i = 0; i < Max_Clientes; i++) {
Numero[i] = i;
}
// Se inicializa el semaforo con valores iniciales...
sem_init(&cuartoespera, 0, numSillas);
sem_init(&SillaBarbero, 0, 1);
sem_init(&AlmohadaBarbero, 0, 0);
sem_init(&CinturonAsiento, 0, 0);
// Se Crea el Barbero.
pthread_create(&btid, NULL, barbero, NULL);
// Se Crea el Cliente.
for (i = 0; i < numClientes; i++) {
pthread_create(&tid[i], NULL, clientes, (void *)&Numero[i]);
}
// Se juntan las hebras a esperar que las otras terminen.
for (i = 0; i < numClientes; i++) {
pthread_join(tid[i],NULL);
}
// Cuando todos los clientes hayan terminado, se elimina la hebra barbero.
Todohecho = 1;
sem_post(&AlmohadaBarbero); // Se despierta al barbero en la salida.
pthread_join(btid,NULL);
return 0;
}
void *clientes(void *Numero) {
int num = *(int *)Numero; // Sale de la tienda y toma algún periodo de tiempo aleatorio para llegar.
printf("hebra %d creada\n", num
); rango_espera(5);
if(numSillas
+1==clientesBarberia
)printf("cliente %d llega a la barberia\nEl cliente abandona la barberia porque esta llena\n", num
); // Espere hasta que haya espacio para abrir en la sala de espera... sem_wait(&cuartoespera);
printf("cliente %d llega a la barberia \ncliente %d entra a la sala de espera.\n************************************Hay %d clientes en la barberia \n", num
, num
,++clientesBarberia
); // Esperar a que la silla del barbero este libre..
//printf("*****************************************\n");
// printf("**Hay %d clientes en la barberia **\n",clientesBarberia);
// printf("*****************************************\n");
sleep(10);
sem_wait(&SillaBarbero); // Si la silla esta libre entonces abandona su lugar en la sala de espera..
sem_post(&cuartoespera); // Despierta el Barbero...
printf("cliente %d llama al barbero.\n", num
); sem_post(&AlmohadaBarbero); // Espera a que el barbero termine de cortar su pelo.
sem_wait(&CinturonAsiento); // Deja la silla.
sem_post(&SillaBarbero);
printf("cliente %d deja la barberia.\n************************************Hay %d clientes en la barberia\n", num
,--clientesBarberia
);
// printf("*****************************************\n");
// printf("**Hay %d clientes en la barberia **\n",clientesBarberia);
//printf("*****************************************\n");
sleep(10);
}
void *barbero(void *junk)
{
// Mientras todavía hayan clientes que atender... El barbero es omniciente y puede decir si hay clientes aún en el camino a su tienda.
while (!Todohecho) { // Esperar hasta que alguien llegue y te despierte..
if( clientesBarberia
==0 ) printf("el barbero esta jugando\n"); sem_wait(&AlmohadaBarbero); // Omitir todo esto al final...
if (!Todohecho)
{ // Tomar un monto aleatorio de tiempo para cortar el cabello del cliente..
printf("el barbero esta cortando el cabello\n"); rango_espera(3);
printf("el barbero ha terminado de cortar el cabello.\n"); // Se libera al cliente cuando ya se le haya cortado el pelo... sem_post(&CinturonAsiento);
}
else {
printf("El barbero ha terminado por el dia.\n"); }
}
}
void rango_espera(int secs) {
int len = 1; // Se genera un numero arbitrario...
sleep(len);
}