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