Skip to content

Instantly share code, notes, and snippets.

@ACruz91
Created November 15, 2012 18:18
Show Gist options
  • Save ACruz91/4080249 to your computer and use it in GitHub Desktop.
Save ACruz91/4080249 to your computer and use it in GitHub Desktop.
Fumadores
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <iostream>
#include <time.h>
using namespace std;
struct nfumador{ int ingrediente; };
/** Declara los semaforos que necesites */
sem_t estanquero, fumador1, fumador2, fumador3, screen;
//Funcion liar cigarro
void liar_cigarro(int fumador){
/** Segun el indice 'fumador' que se le pase, imprime el numero de fumador que lia su cigarro */
sem_wait(&screen);
cout << "El fumador "<<fumador<<" esta liando un cigarro " << endl;
sem_post(&screen);
//reposando, un poco, despues
sleep(5);
}//liar()
//Funcion estanco
void * estanco(void *arg){
//Esta funcion la ejecutara la hebra estanquero
int objeto1, objeto2;
// inicializa semilla aleatoria
srand(time(NULL));
while(1){
/** falta sincronizacion para que el estanquero no se adelante si el ultimo fumador no termino de liar */
sem_wait(&estanquero);
//Ahora el estanquero pone 2 ingredientes aleatorios encima de la mesa
//Que se generan utilizando la funcion rand()
cout << "Poniendo los ingredientes: " << endl;
/** Generar valores distintos dentro del rango [0..2]
* para las variables 'objeto1' y 'objeto2' */
int objeto1=rand()%3;
int objeto2=rand()%3;
do{
if(objeto1== 1 && objeto2==2){
sem_post(&screen);
cout << "Papel y Cerillas" << endl;
sem_wait(&screen);
sem_post(&fumador1);
}
if(objeto1==0 && objeto2==2){
sem_post(&screen);
cout << "Tabaco y Cerillas" << endl;
sem_wait(&screen);
sem_post(&fumador2);
}
if(objeto1==0 && objeto2==1){
sem_post(&screen);
cout << "Tabaco y Papel" << endl;
sem_wait(&screen);
sem_post(&fumador3);
}
}while(objeto1!=objeto2);
/** tengo cuidado que no sean 2 ingredientes iguales */
/** Dependiendo de los valores de las variables 'objeto?'
* imprimir el mensaje apropiado:
* cout << "Papel y Cerillas" << endl;
* cout << "Tabaco y Cerillas" << endl;
* cout << "Tabaco y Papel" << endl;
* Incluyendo en cada opcion anterior la sincronizacion apropiada para el fumador indicado
*/
}//while
}//estanco()
//Funcion fumadora
void * fumar(void *arg){
//Esta funcion la ejecutaran todas las hebras fumadoras
/**Dependiendo de los ingredientes que posea segun su
* numero de fumador ((nFumador*)arg)->ingrediente),
* tendra que sincronizarse con la opcion adecuada de
* la hebra estanquero para obtener el ingrediente
* que le falta para liar su cigarro y fumar
*/
v[nfumadores].ingredientes = atoi(argv[1]);
while(1){
/**Dependiendo del fumador del que se trate, se imprimiran ahora
* uno de los siguientes mensajes:
* cout << "Recoge papel y cerillas el fumador 1" << endl;
* cout << "Recoge tabaco y cerillas el fumador 2" << endl;
* cout << "Recoge tabaco y papel el fumador 3" << endl;
*/
if(nfumador==0){
sem_wait(&screen);
cout << "Recoge papel y cerillas el fumador 1" << endl;
sem_post(&screen);
sem_post(&fumador1);
}
if(nfumador==1){
sem_wait(&screen);
cout << "Recoge tabaco y cerillas el fumador 2" << endl;
sem_post(&screen);
sem_post(&fumador2);
}
if(nfumador==2){
sem_wait(&screen);
cout << "Recoge tabaco y papel el fumador 3" << endl;
sem_post(&screen);
sem_post(&fumador3);
}
//Ojo! que falta la sincronizacion con la hebra estanquero
sem_wait(&estanquero);
/** Avisar al estanquero para que coloque 2 nuevos ingredientes */
sem_post(&estanquero);
/** Ahora, se llama a la funcion liar cigarro */
liar_cigarro(nfumador);
/** Imprimir uno de los siguientes mensajes para informar de quien fuma
* cout << "Fumando el fumador 1" << endl;
* cout << "Fumando el fumador 2" << endl;
* cout << "Fumando el fumador 3" << endl;
*/
if(nfumador==0){
sem_wait(&screen);
cout << "Fumando el fumador 1" << endl;
sem_post(&screen);
sem_post(&fumador1);
}
if(nfumador==1){
sem_wait(&screen);
cout << "Fumando el fumador 2" << endl;
sem_post(&screen);
sem_post(&fumador2);
}
if(nfumador==2){
sem_wait(&screen);
cout << "Fumando el fumador 3" << endl;
sem_post(&screen);
sem_post(&fumador3);
}
//Fumar lleva un tiempo, por supuesto!
sleep(10);
//Ir acabando este turno ordenadamente
cout << "Termina de fumar el fumador "<<nfumador<< endl;
}//while
}//fumadora()
int main (int argc, char *argv[]){
// Declarar las 4 hebras necesarias para implementarlo
pthread_t estanqueros, fumadores1, fumadores2, fumadores3;
/** Iniciar 'ingrediente' de la estructura 'nFumador' con un valor:[0..2],
* asociado a cada hebra fumadora para diferenciarlas */
nfumador *v[3];
/** Y crearse una variable dinamica para contener el valor de 'ingrediente' para cada fumador
//...el fumador ? con tabaco
//...el fumador ? con papel
//...el fumador ? con cerillas
**** que se pasara como cuarto argumento en la funcion de creacion de hebra correspondiente */
v= new nfumador [3];
v[0].ingrediente=0;
v[1].ingrediente=1;
v[2].ingrediente=2;
/** Iniciar los semaforos, teniendo en cuenta que la hebra estanquero ha de comenzar
* la simulacion poniendo los primeros ingredientes */
sem_init(&estanquero, 0, 1);
sem_init(&fumador1, 0, 0);
sem_init(&fumador2, 0, 0);
sem_init(&fumador3, 0, 0);
/** Crear y lanzar la ejecucion de 4 hebras: 3 fumadores y 1 estanquero,
* la funcionalidad vendra dada por una de funciones anteriormente
* descritas como: estanco() y fumar() segun el tipo de hebra del que se trate */
pthread_create(&estanqueros, NULL, estanco, NULL);
pthread_create(&fumadores1, NULL, fumar, NULL);
pthread_create(&fumadores2, NULL, fumar, NULL);
pthread_create(&fumadores3, NULL, fumar, NULL);
/** Recoger las hebras al terminar, segun el orden de creacion */
pthread_join(estanqueros, NULL);
pthread_join(fumadores1, NULL);
pthread_join(fumadores2, NULL);
pthread_join(fumadores3, NULL);
/** Destrucción de los Semáforos */
sem_destroy(&estanquero);
sem_destroy(&fumador1);
sem_destroy(&fumador2);
sem_destroy(&fumador3);
cout << "Fin del programa \n" << endl ;
/** No olvidar destruir los semaforos antes de terminar el programa */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment