jueves, 17 de septiembre de 2020

Código de Barbero Dormilon (C++)

Utilizando libreria thread y semaphore.
Se considera lo siguiente:
- las sillas disponibles que tiene la barberia, si estas estan llenas ya no se puede admitir clientes.
- el barbero empieza durmiendo y quien lo despierte sera el primero en atender; se tomara en cuenta el orden de llegada 

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <windows.h>
#include <math.h>
using namespace std;
typedef enum {LLENO, CORTADO} respuesta;

#define NUM_CLIENTES 4 // Numero de clientes
#define N 3 // Numero max de clientes en la barberia

int clientes = 0; // Numero de clientes en la barberia
int quien = -1; // Cliente que esta siendo atendido

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; //para excl mutua ops monitor
pthread_cond_t silla, sillon, sube_sillon, dormir;

void pcliente(int i, char *s){printf("Cliente: %d -> %s\n",i,s);}

void pbarbero (char *s) {printf("Barbero: -> %s\n", s);}

//———————————– inicio monitor
int entra_barberia(int i) {

    pcliente(i,"ENTRO en la barberia");
    pthread_mutex_lock( &m );

    if (clientes >= N){
        pthread_mutex_unlock(&m ); return LLENO; // No cabe
    }else{
        clientes++;
        if (clientes==1) {
            pcliente(i,"DESPIERTO al barbero");
            pthread_cond_signal(&dormir);
        }else {
            pcliente(i,"ESPERO mi turno");
            pthread_cond_wait(&silla, &m );
            pthread_cond_signal(&sube_sillon);
        }
        quien = i;
        pthread_cond_wait (&sillon, &m ); /* Esperar a que acabe el corte.*/
        pcliente(i,"Se fue satisfactoriamente \n");
        pthread_mutex_unlock(&m );
        return CORTADO;
    }
}

void espera_cliente() {
    pthread_mutex_lock( &m );
    if (!clientes) {
        pbarbero("Me voy a dormir");
        pthread_cond_wait(&dormir,&m);
        pbarbero("Ya voy!!");
    }
    else {
        pbarbero("Que pase el siguiente...");
        pthread_cond_signal(&silla );
        pthread_cond_wait(&sube_sillon,&m);
    }
    pthread_mutex_unlock( &m);
}

void fin_corte() {
    pthread_mutex_lock(&m);
    pthread_cond_signal(&sillon); clientes--; pbarbero("FIN CORTE");
    pthread_mutex_unlock(&m);
}

void corta_pelo() {
    int r=rand()%10000;
    //usleep(10); (con sube_sillon, ya no es necesario)
    pthread_mutex_lock(&m ); // Protege el acceso a la variable “quien”
    pbarbero("Cortando el pelo.....");
    printf(" al cliente %d (%d useg.)\n",quien,r);
    pthread_mutex_unlock(&m );
    Sleep(r);
}

void da_una_vuelta(int i, int t) {
    pcliente(i,"Voy a dar una vuelta");
    printf(" durante (%d useg.)\n",t);
    Sleep(t);
    pcliente(i,"Vengo de dar una vuelta");
}
// ——————————- fin monitor

void *cliente(void *arg) {
    int i=(intptr_t) arg;
    do {
        da_una_vuelta(i,rand()%10000);
    } while (entra_barberia(i)==LLENO);
}

void *barbero(void *arg) {
    while (1) {
        espera_cliente();
        corta_pelo();
        fin_corte();
    }
}

int main(void) {
    int i;
    pthread_t id_clientes[NUM_CLIENTES], id_barbero;
    srand( (unsigned)time( NULL ) );

    pthread_cond_init(&silla, 0);
    pthread_cond_init(&sillon, 0);
    pthread_cond_init(&sube_sillon, 0);
    pthread_cond_init(&dormir, 0);

    pthread_create(&id_barbero, NULL, barbero, NULL); Sleep(1);
    for (i=0; i<NUM_CLIENTES; i++) pthread_create(&id_clientes[i], NULL, cliente, (void *) i);
    for (i=0; i<NUM_CLIENTES; i++) pthread_join(id_clientes[i], NULL);
}

Ejecución del programa:



0 comentarios:

Publicar un comentario