martes, 11 de diciembre de 2012

Trabajo voluntario de concurrencia - Fumadores SO 12/13

He aquí el pseudocódigo de la práctica voluntaria:




-- Fumadores --

-- Definición de tipos --

definir TIPOS 3
definir ITERACIONESF 20
definir ITERACIONESP 50
definir FUMADORES    3

-- Variables globales --

entero         fumadores[TIPOS][TIPOS];
entero         mesa[TIPOS];
caracter     traduccion[TIPOS][100]={"cerillas","papel","tabaco"};


-- Semaforos --

semaforo mutex,necesidad,producido;

-- Prototipo de funciones --

vacio *fumador(vacio *id);
vacio *productor();
vacio cogerLoQueNecesito(entero id);

-- Programa pincipal --

entero principal()
{
    hilo hiloProductor[1];
    hilo hilosFumadores[FUMADORES];
    entero i,id[FUMADORES];estado;
   
    variableExterna semaforo mutex, necesidad, producido;
    variableExterna entero fumadores[TIPOS][TIPOS],mesa[TIPOS];
   
    random(tiempo(NULO));
   
    -- Inicializacion de variables --
    -- FUMADOR 0
    fumadores[0][0]=0; fumadores[0][1]=25; fumadores[0][2]=25;
    -- FUMADOR 1
    fumadores[1][0]=25; fumadores[1][1]=0; fumadores[1][2]=25;
    -- FUMADOR 2
    fumadores[2][0]=25; fumadores[2][1]=25; fumadores[2][2]=0;
    -- MESA
    mesa[0]=0; mesa[1]=0; mesa[2]=0;

    iniciar_semilla(&mutex,1,0);
    iniciar_semilla(&necesidad,1,1);
    iniciar_semilla(&producido,1,0);
   
    Si ((estado = crear_hilo(&hiloProductor[0],Nulo,productor,Nulo)))
    Salir (estado);
   
    Para(i=0;i<FUMADORES;i++)
    {
        id[i]=i;
        Si ((estado = crear_hilo(&hilosFumadores[i],Nulo,fumador,(vacio *) &id[i])))
        Salir (estado);
    }
   
    union_hilo(hilosFumadores[i], Nulo);
   
    Para(i=0;i<FUMADORES;i++)
    {
        union_hilo(hilosFumadores[i],Nulo);
    }
    devolver(0);
}

vacio *fumador(vacio *id)
{
    entero *nombre, i, j, vez=0;
   
    variableExterna semaforo mutex,necesidad,producido;
   
    nombre=(int *) id;
   
    Escribir("Comienza el fumador *nombre");
   
    Para(i=0;i<ITER;i++)
    {
        semaforoEsperar(&producido);
        cogerLoQueNecesito(*nombre);
       
        mientras(fumador[*nombre][0]>0 && fumadores[*nombre][1]>0 && fumadores[*nombre][2]>0)
        {
            Para(j=0;j<TIPOS;j++)
            {
                fumadores[*nombre][j]-=1;
                vez++;
                Escribir("El fumador *nombre esta fumando vez");
            }
        }
       
        dormir(2);
       
        Escribir("El fumador *nombre necesita coger cosas");
        semaforoEnviar(&necesidad);
       
       
           
    }
    hiloSalir(Nulo);
}
   
vacio *productor()
{

    entero i,tipo,U;
   
    variableExterna semaforo mutex,necesidad,producido;
    variableExterna entero mesa[TIPOS];
    variableExterna caracter traduccion[TIPOS][100];
   
    para(i=0;i<ITERACIONESP;i++)
    {
        semaforoEsperar(&necesidad);
        semaforoEsperar(&mutex);
       
        tipo=random()%3;
        U=random()%10;
        mesa[tipo]+=U;
        Escribir("Productor produjo traduccion[tipo] --> U");
       
        semaforoEnviar(&mutex);
        semaforoEnviar(&producido);
    }
    hiloSalir(Nulo);
}

vacio cogerLoQueNecesito(entero id)
{
    entero j, cogido=;
   
    variableExterna semaforo mutex, producido;
    variableExterna mesa[TIPOS], fumadores[TIPOS][TIPOS];
    variableExterna caracter traduccion[TIPOS][100];
   
    semillaEsperar(&mutex);
    Para(j=0;j<TIPOS;j++)
    {
        Si(fumadores[id][j]==0)
        {
            Si(mesa[0]>0)
            {
                fumadores[id][j]=mesa[j];
                Escribir("El Fumador (id) cogió mesa[j] de traduccion[j]");
                mesa[j]=0;
                cogido=1;
            }
        }
    }
    semaforoEnviar(&mutex);
}


He aquí el código en C de los fumadores:



//Ejercicio voluntario fumadoress !!

//Librerias nesesarias
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>

//DEFINES
#define TIPOS 3 //cerillas-tabaco-papel
#define ITER 20 //iteraciones del fumador
#define ITERP 50 //Iteraciones del productor
#define F 3 //Numero de fumadores

//Variables globales
int f[TIPOS][TIPOS];
int mesa[TIPOS];
char traducion[TIPOS][100]={"serillas", "Papel", "Tabaco"};

//Semaforos
sem_t mutex,nesesidad,producido;


//Prototipos de funciones
void *fumador(void *id);
void *productor();
void cojerLoQueNesesito(int id);

//Programa principal
int main()
{
    pthread_t hiloP[1];
    pthread_t hilosF[F];
    int i,id[F],status;

    extern sem_t mutex, nesesidad, producido;
    extern int f[TIPOS][TIPOS],mesa[TIPOS];

    srand(time(NULL));

    // **** Inicializaci�n de variables ****
    //FUMADOR 0
    f[0][0]=0; f[0][1]=25; f[0][2]=25;
    //FUMADOR 1
    f[1][0]=25; f[1][1]=0; f[1][2]=25;
    //FUMADOR 2
    f[2][0]=25; f[2][1]=25; f[2][2]=0;
    //mesa
    mesa[0]=0; mesa[1]=0; mesa[2]=0;

    //SEMAFOROS
    sem_init(&mutex, 1, 0);
    sem_init(&nesesidad, 1, 1);
    sem_init(&producido, 1, 0);

    //hilo productor
    if ((status = pthread_create(&hiloP[0], NULL, productor, NULL)))
        exit(status);

    for(i=0;i<F;i++)
    {   
        id[i]=i;
        if ((status = pthread_create(&hilosF[i], NULL, fumador, (void *) &id[i])))
            exit(status);
    }

    //esperar hasta finalizar el productor
    pthread_join(hiloP[0], NULL);

   
    //esperar hasta finalizar los hilos fumadores
    for (i = 0; i < F; i++)
    {
        pthread_join(hilosF[i], NULL);
    }

    return (0);
}
//funcion para los fumadores
void *fumador(void *id)
{
    int *nombre, i, j, vez=0;

    extern sem_t mutex, nesesidad, producido;
   
    nombre=(int *) id;

    printf("\nComienza el fumador %d", *nombre);

    for(i=0;i<ITER;i++)
    {
        sem_wait(&producido); //Espera hasta que el productor haya producido algo

        //comprueba que es lo que nesesita y si nesesita algo lo coje
        cojerLoQueNesesito(*nombre);


        while(f[*nombre][0]>0 &&f[*nombre][1]>0 &&f[*nombre][2]>0) //fuma mientras tenga
        {
            for(j=0;j<TIPOS;j++)//Gasta una unidad de cada cosa           
                f[*nombre][j]-=1;
            vez++;
            printf("\nEl fumador %d esta fumado %d", *nombre, vez);
        }

        //ha este punto solo se llega si no se tiene nada mas qu fumar
        sleep(2);
        printf("\nElfumador %d nesesita coger cosas", *nombre);

        sem_post(&nesesidad); //Espera hasta que el productor haya producido algo
    }
    pthread_exit(NULL);
}

//funcion para el poductor
void *productor()
{
    int i,tipo,U;

    extern sem_t mutex, nesesidad, producido;
    extern int mesa[TIPOS];
    extern char traducion[TIPOS][100];

    for(i=0;i<ITERP;i++)
    {
        sem_wait(&nesesidad);//Espera ha que el fumador nesesite algo
        sem_wait(&mutex);

        tipo=rand() %3;
        U=rand() %10;
        mesa[tipo]+=U;   
        printf("\nProductor produjó %s --> %d", traducion[tipo], U);

        sem_post(&mutex);
        sem_post(&producido);//Indica que ya hay nuevas cosas producidas
    }

    pthread_exit(NULL);
}

//Esta funcion solo coje lo que el fumador nesesita
void cojerLoQueNesesito(int id)
{
    int j, cojido=0;

    extern sem_t mutex, producido;
    extern int mesa[TIPOS], f[TIPOS][TIPOS];
    extern char traducion[TIPOS][100];

    sem_wait(&mutex);
    for(j=0;j<TIPOS;j++)
    {
        if(f[id][j]==0)
        {
            if(mesa[0]>0)
            {
                f[id][j]=mesa[j];
                printf("\n\nEl Fumador %d cojió %d de %s ", id, mesa[j], traducion[j]);
                mesa[j]=0;
                cojido=1;
            }
        }
    }
    sem_post(&mutex);
}

No hay comentarios:

Publicar un comentario