Primera implementación
En esta primera aproximación resolvemos el que los procesos compitan por un
mismo recurso mediante un único semáforo.Este sincroniza el acceso a la
zona de memoria compartida de uno u otro proceso de tal forma que el carácter
que vaya a tratar el proceso productor sea leído anteriormente por el consumidor.
De esta manera, el padre puede ir leyendo caracteres, sin esperar a que sean tratados por
el hijo, mientras que el proceso hijo tiene que esperar a que el padre haya leído los
caracteres para tratarlos.
El semáforo actúa de contador de la siguiente manera:
- En el proceso productor incrementamos en uno la variable semáforo,
lo que indica que tenemos un elemento más.
- El proceso consumidor, no podrá decrementar el semáforo cuando este
sea menor que cero, es decir, cuando no tengamos elementos.
La implementación es la siguiente:
#include <stdio.h>
#include "rshmem.h"
int sema; /*semaforos */
/* FUNCION MAIN */
void main(int argc,char *argv[])
{
key_t clave_sema; /*clave semaforo*/
int pid;/*variable auxiliar */
int *p1,/*puntero de escritura en buffer */
*p2;/*puntero de lectura en buffer */
/* control de paso de argumentos */
if(argc!=2){
(void) printf("Error en la entrada de argumentos\n");
exit(1);
}
/* obtencion de una clave cualquiera para el recurso*/
if((key_t)-1==(clave_sema=ftok("con1.c",'s'))){
(void)fprintf(stderr,"Main:Error al crear la clave con ftok()\n");
exit(1);
}
/* reserva de memoria */
if(!crearMemoria())
(void)fprintf(stderr,"Error al crear memoria\n");
p1=(int *)memoria;
*p1=NULL;
p2=p1;
/* creacion del semaforo*/
if(-1==(sema=semCreate(clave_sema,0))){
(void)fprintf(stderr,"Main:No se puede abrir el semaforo\n");
exit(1);
}
printf("COMIENZO\n");
/* CREACION DE DOS PROCESOS CONCURRENTES */
if((pid=fork())!=0){ /*PID!=0*/
/*********************PROCESO 1 (produce) ******************/
int valor;/*variable con el dato leido del fichero*/
FILE *ftp=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*/
while(EOF!=(valor=fgetc(ftp))){
*p1=valor; /*dato en la posicion p1*/
(void)fprintf(stderr,"\"%c\"-> p\n", *p1);fflush(0);
p1++; /*avanzo puntero*/
semSignal(sema);
}
semClose(sema);
*p1=EOF;
fclose(ftp); /*cierro fichero de entrada*/
exit(0);
}/****FIN PROCESO 1****/
else{
/********************PROCESO 2*************************/
int valor;/*variable auxiliar*/
if(-1==(sema=semOpen(clave_sema)))
(void)fprintf(stderr,"No tengo el cualificador de sema\n");
do{ /*TRATAMIENTO*/
/*apertura del semaforo*/
semWait(sema);
valor=*p2;
p2++;/*avanzo el puntero*/
printf(" p -> \"%c\" (%d): ", valor, (int) valor);fflush(0);
/****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);
semClose(sema);
/*eliminar memoria compartida */
if(!eliminarMemoria())
(void)fprintf(stderr,"Error al eliminar memoria\n");
exit(0);
}/****FIN PROCESO 2****/
}/***FIN MAIN****/
Volver a la Introducción
Ir a segunda implementación