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);
}