Segunda implementación


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