En esta segunda aproximación hemos utilizado tres semáforos para la implementación, que controlan cada proceso hasta que el recurso está disponible. Los tres semáforos que empleamos son:
Para la implementación se han creado las siguientes funciones:
La implementación es la siguiente:
#include "rshmem.h"
#include <sys/sem.h>
#include <stdlib.h>
#define N 20
void main(int argc,char *argv[]) {
key_t claveMutex,claveLleno,claveVacio; /* cualificadores semáforos */
int Mutex,Lleno,Vacio; /* semáforos */
int *finProc =NULL;
int *salida =NULL;
int *entrada =NULL;
int *contador=NULL;
int *array =NULL; /* almacén de elementos */
/* control de paso de argumentos */
if(argc!=2){
(void) printf("Error en la entrada de argumentos\n");
exit(1);
}
/* obtener una clave cualquiera para el recurso ipc */
if ((key_t) -1 == (claveMutex = ftok("con1.c", 's')) ||
(key_t) -1 == (claveLleno = ftok("con1.c", 'w')) ||
(key_t) -1 == (claveVacio = ftok("con1.c", 'j'))) {
fprintf(stderr,"main: Error al crear la clave con ftok(3)\n");
exit(1);
}
/* creamos los semáforos, asignando los valores iniciales */
if (-1 ==(Mutex = semCreate(claveMutex,1))){
fprintf(stderr,"main: No puede crear el semaforo\n");
exit(1);
}
if (-1 ==(Lleno = semCreate(claveLleno,0))){
fprintf(stderr,"main: No puede crear el semaforo\n");
semClose(Mutex);
exit(1);
}
if (-1 ==(Vacio = semCreate(claveVacio,N))){
fprintf(stderr,"main: No puede crear el semaforo\n");
semClose(Mutex);
semClose(Lleno);
exit(1);
}
/* creamos zona de memoria compartida */
if (!crearMemoria()) {
fprintf(stderr," error de crearMemoria\n");
semClose(Mutex);
semClose(Lleno);
semClose(Vacio);
exit(1);
}
/******Funcion para inicializar punteros de memoria compartida******/
inicio((int *)memoria,N);
if (0!=fork()) { /* proceso padre, el productor */
int valor;
FILE *fpt =NULL; /*puntero al fichero de entrada*/
if((ftp=fopen(argv[1],"r"))==NULL){
(void) fprintf(stderr,"Error en la apertura del fichero\n");
if(!eliminarMemoria())
(void)fprintf(stderr,"Error al eliminar memoria\n");
exit(2);
}
/*tratamiento de lectura del fichero*/
do{
valor=fgetc(ftp);
while(((entrada+1)%N)==salida);
semWait(Vacio); /*mira si hay sitio*/
/******Funcion que escribe el dato en el Buffer******/
P_Buffer(valor,&array,&entrada,&contador,&Mutex,&Lleno,N);
}while(EOF!=valor);
*array=EOF;
while(! *finProc);
if(!eliminarMemoria())
fprintf(stderr,"Error al eliminar la memoria\n");
fclose(ftp); /*cierro fichero de entrada*/
semClose(Mutex);
semClose(Lleno);
semClose(Vacio);
exit(0);
} else { /* proceso hijo, consumidor */
int valor;
if (-1 == (Mutex = semOpen(claveMutex)))
fprintf(stderr," No tengo el cualificador de Mutex\n");
if (-1 == (Lleno = semOpen(claveLleno)))
fprintf(stderr," No tengo el cualificador de Lleno\n");
if (-1 == (Vacio = semOpen(claveVacio)))
fprintf(stderr," No tengo el cualificador de Vacio\n");
do{
while(entrada==salida);
semWait(Lleno); /* mira si hay algún elemento */
/******Funcion que recoge el dato de la zona de memoria compartida******/
valor=Buffer_C(&salida,&array,&contador,,&Mutex,&Vacio,N);
/****IMPRESION DE MENSAJES ****/
switch (valor) {
case '0':
printf("nivel bajo\n");fflush(0);
break;
case '1':
printf("nivel medio\n");fflush(0);
break;
case '2':
printf("nivel alto\n");fflush(0);
}
}while(valor!=EOF);
/* termina */
semClose(Mutex);
semClose(Lleno);
semClose(Vacio);
*finProc = 1;
exit(0);
}
}
void inicio(int *memo,int N1){
contador=memo;
salida=contador+sizeof(int);
entrada=salida+sizeof(int);
array=entrada+sizeof(int);
finProc=array+sizeof(int)*N1;
*contador=0;
*salida=0;
*entrada=0;
*finProc=0;
}
void P_Buffer(int dato,int *array,int * entrada,int * contador,
int *Mutex,int *Lleno,int N1){
semWait(Mutex); /*entrada s.c.*/
*array[*entrada]=dato; /*dato en la posicion p1*/
(void) fprintf(stderr,"\"%c\"-> p\n", *p1);fflush(0);
entrada=(entrada+1)%N1; /*avanzo puntero*/
(*contador)++;
semSignal(Mutex); /*salida s.c.*/
semSignal(Lleno); /*hay un elemento más*/
}
int Buffer_C(int *salida,int *array,int * contador,
int * Mutex,int *Vacio,int N1){
semWait(Mutex); /* entrada s.c. */
dato=array[*salida];
salida=(salida+1)%N1;
*contador=*contador-1;
printf(" p -> \"%c\" (%d): ", valor, (int) valor);fflush(0);
semSignal(Mutex); /* salida s.c. */
semSignal(Vacio); /* hay un elemento menos */
return(dato);
}
Volver a la Introducción Ir a primera implementación