Universidad de Costa Rica

Escuela de Ciencias de la Computación e Informática

CI-0122 Sistemas operativos

Ejemplos

CI0122 / Ejemplos


#include <QCoreApplication>
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <vector>
#include <semaphore.h>
#define MAX_CLIENTES 2
#define TIEMPO_ESPERA 100
#define PINHA 5
#define CAS 4

/*Memoria compartida, entre otros*/

bool barAbierto;
bool guaro;
int barra[6];

sem_t semMesero;

/*DECLARACION DE MUTEX*/

static pthread_mutex_t bebidas[6];
pthread_mutex_t hayPaco = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t consola = PTHREAD_MUTEX_INITIALIZER;

std::string  nombre_bebidas[] = {"whisky","anís","ginebra","conhac","cas","piña"};

/*Declaración adelantada de métodos*/
void *cliente (void*);
void *policia (void*);


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    barAbierto = true;
    guaro = true;


    sem_init(&semMesero, 0, 2);             //Cuado es negativo se bloquea, xq no se puede aumentar más.

    /*Se inicializa la barra en -1 para indicar que los meseros están disponibles.*/
    for(int i =0; i<6; barra[i]=-1,i++);

    for(int i=0; i<6; i++){
       pthread_mutex_init(&bebidas[i], NULL);
    }

    srand (time(NULL));
    int numClientes = 0;
    pthread_t oficial;
    pthread_t *clientes;

    clientes = new pthread_t[MAX_CLIENTES];

    pthread_create(&oficial, NULL, &policia, NULL);

    /*En este ciclo se crean los clientes*/
    while(numClientes!=MAX_CLIENTES){
        if(rand()%3 == 0){
            pthread_create(&clientes[numClientes], NULL, &cliente, (void *)(intptr_t)numClientes);
            numClientes++;
        }
    }

    /*Eliminar a los clientes.*/

    for(int i=0; i<MAX_CLIENTES;i++){
        if(!pthread_join(clientes[i],NULL)){
            pthread_mutex_unlock(&consola);
            std::cout<<"Thread cliente:  eliminado."<< std::endl;
            pthread_mutex_unlock(&consola);
        }
    }



    for(int i=0; i<6; pthread_mutex_destroy(&bebidas[i]), i++);

    barAbierto=false;


    /*Eliminar hilo restante*/

    if(!pthread_join(oficial, NULL)){
        pthread_mutex_lock(&consola);
        std::cout<<"Thread policia eliminado. "<< std::endl;
        pthread_mutex_unlock(&consola);
    }

    pthread_mutex_destroy(&hayPaco);
    pthread_mutex_destroy(&consola);
    sem_close(&semMesero);
    sem_destroy(&semMesero);

    pthread_exit(NULL);


    return a.exec();
}


std::string Ordenar(int b1, int b2){

    int mesero = -1;
    int pos =0;
    while(mesero==-1){
        if(barra[pos]==-1) {
            mesero=pos/2;
            barra[pos]=0;
        }
        pos+=2;
    }
    pthread_mutex_lock(&consola);
    std::cout<<"hOLA "<<mesero<<std::endl;
    pthread_mutex_unlock(&consola);
    usleep(800000);


    bool servido=false;



    /*Solo se puede entrar si se sabe si hay o no policía



    while(servido==false){
        while(servido == false && guaro==false && pthread_mutex_trylock(&bebidas[PINHA])==0){
            if(0==(pthread_mutex_trylock(&bebidas[CAS]))){
                barra[mesero]=PINHA;
                barra[mesero+1]=CAS;
                pthread_mutex_unlock(&bebidas[PINHA]);
                pthread_mutex_unlock(&bebidas[CAS]);
                servido = true;
            }else{
                pthread_mutex_unlock(&bebidas[PINHA]);
            }
        }
        while(servido ==false && guaro==true && pthread_mutex_trylock(&bebidas[b1])==0){
            if(0==(pthread_mutex_trylock(&bebidas[b2]))){
                barra[mesero]=b1;
                barra[mesero+1]=b2;
                pthread_mutex_unlock(&bebidas[b1]);
                pthread_mutex_unlock(&bebidas[b2]);
                servido = true;
            }else{
                pthread_mutex_unlock(&bebidas[b1]);
            }
        }
    }

    pthread_mutex_lock(&consola);
    std::string orden= "está tomado "+nombre_bebidas[barra[mesero]]+" con "+nombre_bebidas[barra[mesero+1]];
    pthread_mutex_unlock(&consola);
    */

    barra[mesero]=-1;
    barra[mesero+1]=-1;

    std::string orden = "vas a mamarrr!";
    usleep(200);
    return orden;
}

void *cliente(void *a){
    srand (time(NULL));
    int ran;
    do{

        /*El cliente decide que va a ordenar*/
        int bebida1 = random() % 6;
        int bebida2 = random() % 6;

        //En el caso de que la bebida1 sea igual a la bebida2
        while(bebida1 == bebida2){
            bebida1 = random() % 6;
            bebida2 = random() % 6;
        }

        sem_wait(&semMesero); //Espera por un mesero



        int id = (intptr_t) a;
        std::string orden = "El cliente "+std::to_string(id)+" está tomando: "+Ordenar(bebida1, bebida2);



        pthread_mutex_lock(&consola);
        std::cout<<orden<<std::endl;
        pthread_mutex_unlock(&consola);


    sem_post(&semMesero);
    usleep(random() % 2);
    ran = random()%3;
    }while(ran);

    pthread_exit(NULL);
}


void *policia(void *ptrVigilar){

    while(barAbierto){
        if(random()%20<5){
            guaro = false;
            usleep(random() %400);
            pthread_mutex_lock(&consola);
            std::cout << "El policia esta en vigilia " << std::endl;
            pthread_mutex_unlock(&consola);


            usleep(random() %400); // policia esta vigilando
            guaro = true;
            pthread_mutex_lock(&consola);
            std::cout <<"El policia ha salido del bar " << std::endl;
            pthread_mutex_unlock(&consola);

        }

        usleep(random() % 600); // policia no esta vigilando
    }
    pthread_exit(NULL);
}