|
Si quieres ir a la aproximación pincha aqui
Si quieres ir a la aproximación pincha aqui
Primera aproximación
En esta primera aproximación resolvemos el que los procesos compitan por unmismo recurso mediante un 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 hijo sea el leído anteriormente por el padre, es decir, el padre no leerá otro
carácter hasta que no haya sido tratado por el hijo . La implementación es la siguiente:
#include "rshmem.h"
#include <string.h>
int main(int argc,char *argv[ ]){
/* DECLARACIONES DE VARIABLES */
int* acaracter; /* contador de caracter antiguo */
int * ncaracter; /* variable compartida contador de caracter actual */
char* caracter; /* variable compartida por los dos procesos almacen
del caracter leido del fichero */
int mutex; /* semaforo */
key_t claveMutex; /* clave semaforo mutex */
/* control del paso de argumentos */
if(argc!=3){
fprintf(stderr, "Main: Error en el paso de argumentos.");
exit(3);
}
/* obtener una clave cualquiera para el recurso ipc */
if((key_t)-1 == (claveMutex=ftok("con1.c" , 's'))){
fprintf( stderr, "Main: Error al crear la clave con ftok()\n");
exit(1);
}
/* crear el semaforo */
if(-1==(mutex=semCreate(claveMutex, 1))){
fprintf(stderr, "Main: No se puede crear el semaforo\n");
exit(1);
}
/* crear zona de memoria compartida */
if(!crearMemoria())
fprintf(stderr, "Error al crear memoria compartida \n");
ncaracter = (int*) memoria ; /* contador de caracteres leidos */
acaracter = (int*) ncaracter + sizeof(int); /* variable auxiliar */
caracter = (char*) acaracter + sizeof(int); /* variable s.c. */
*ncaracter=0;
*acaracter=0;
*caracter=NULL;
if(0!=fork()){ /* PROCESO PADRE */
int i; /* contador */
char linea[85]; /* variable donde se guardan las lineas leidas */
FILE *fpt=NULL; /* puntero al fichero entrada*/
/* apertura del fichero entrada*/
if((fpt=fopen(argv[1], "r"))==NULL){
fprintf(stderr,"No se puede abrir %s\n",argv[1]);
semClose(mutex);
exit(2);
}
/* Tratamiento de LECTURA del fichero */
while( NULL!=fgets(linea, 81, fpt)){
if (strlen(linea)<80) break;
linea[strlen(linea)]=' ';
for(i=0; i<=80; ){
semWait(mutex);
if (*acaracter == *ncaracter) {
*caracter=linea[i];
(*ncaracter)++;
i++;
}
semSignal(mutex);
}
}
(*ncaracter)=-1;
semClose(mutex);
fclose(fpt);
exit(0);
}else{ /* PROCESO HIJO */
char caract; /* variable auxiliar */
enum {INICIO, TRANSITO} estado = INICIO ;
enum {SI, NO} leido = NO ;
FILE *fptsali; /* puntero fichero salida */
/* apertura del fichero salida */
if((fptsali=fopen(argv[2],"w"))==NULL){
fprintf(stderr,"No se puede abrir %s\n",argv[2]);
exit(2);
}
/* apertura del semaforo */
if(-1 == (mutex = semOpen(claveMutex)))
fprintf(stderr, "No tengo el cualificador de mutex\n");
/* Tratamiento de SUSTITUCION */
do{
semWait(mutex);
if(*acaracter!=(*ncaracter)){
caract =(*caracter);
leido =SI;
*acaracter = *acaracter + 1;
}
semSignal(mutex);
if(leido==SI){
switch(caract){
case '*':
if(estado==INICIO){
estado=TRANSITO;
}else{
fprintf(stdout, "^"); fflush(stdout);
fprintf(fptsali,"^");
estado=INICIO;
}
break ;
default:
if(estado==INICIO) {
fprintf(stdout,"%c",caract); fflush(stdout);
fprintf(fptsali,"%c",caract);
} else{
fprintf(stdout,"*%c",caract); fflush(stdout);
fprintf(fptsali,"*%c",caract);
estado=INICIO;
}
}/* fin del switch */
leido=NO;
}/* fin del if(leido) */
}while (*ncaracter!=-1);
semClose(mutex);
close(fptsali);
/* eliminar memoria compartida */
if(!eliminarMemoria())
fprintf(stderr, "Error al eliminar memoria compartida\n");
exit(0);
}/* fin else proceso hijo */
}/* fin main() */
Segunda aproximación
En esta segunda aproximación resolvemos el que los procesos compitan por unmismo recurso mediante dos semáforos. La sincronización de semáforos se realiza del siguiente modo: cada proceso activa o desactiva el semáforo del otro proceso. Por ejemplo,
el proceso padre lee un carácter si el hijo ha puesto en verde su semáforo, así mismo el
proceso hijo recogerá el caracter leído por el padre cuando éste ponga el semáforo del hijo
en verde.La implememtación es la siguiente.
![]()
![]()
#include "rshmem.h" int main(int argc, char *argv[]){ /*DECLARACIONES DE VARIABLES*/ key_t claveMutex; /* clave semaforo mutex*/ key_t bclaveMutex; /* clave semaforo bmutex*/ char *caracter; /*variable compartida por los dos procesos almacen del caracter leido del fichero*/ int mutex; /* semaforo*/ int bmutex; /* semaforo*/ /* control del paso de argumentos*/ if(argc!=3){ fprintf(stderr,"Main: Error en el paso de argumentos\n"); exit(3); } /* obtener una clave cualquiera para el caracter ipc */ if((key_t)-1 == (claveMutex=ftok("con2.c" , 's'))){ fprintf( stderr, "Main: Error al crear la clave con ftok()\n"); exit(1); } /* crear el semaforo mutex */ if(-1==(mutex=semCreate(claveMutex, 1))){ fprintf(stderr, "Main: No se puede crear el semaforo\n"); exit(1); } /* obtener una clave cualquiera para el caracter ipc */ if((key_t)-1 == (bclaveMutex=ftok("con2.c" , 'b'))){ fprintf( stderr, "Main: Error al crear la clave con ftok()\n"); exit(1); } /* crear el semaforo bmutex */ if(-1==(bmutex=semCreate(bclaveMutex, 0))){ fprintf(stderr, "Main: No se puede crear el semaforo\n"); exit(1); } /* crear zona de memoria compartida */ if(!crearMemoria()) fprintf(stderr, "Error al crear memoria compartida \n"); caracter = (char *)memoria ; /*variable s.c.*/ *caracter=NULL; if(0!=fork()){ /*PROCESO PADRE*/ int i=0; /*variable contador*/ char caract; /*variable auxiliar*/ FILE *fpt=NULL; /*punterp al fichero entrada*/ /* apertura fichero entrada*/ if((fpt=fopen(argv[1], "r"))==NULL){ fprintf(stderr,"No se puede abrir el %s\n",argv[1]); semClose(mutex); exit(2); } i = 0; /* Tratamiento LECTURA del fichero*/ while (EOF != (caract = fgetc(fpt))) { semWait(mutex); *caracter = caract ; semSignal(bmutex); if (i == 79) { semWait(mutex); *caracter = ' '; semSignal(bmutex); i = 0; }else i++; } semWait(mutex); (*caracter)=EOF; semSignal(bmutex); semClose(mutex); semClose(bmutex); fclose(fpt); exit(0); }else{ /* PROCESO HIJO*/ char caract; enum {INICIO, TRANSITO} estado = INICIO ; enum {SI, NO} leido = NO ; FILE *fptsali=NULL; /*puntero al fichero salida*/ /* apertura del fichero salida*/ if((fptsali=fopen(argv[2],"w"))==NULL){ fprintf(stderr , "No se puede abrir %s\n",argv[2]); exit(2); } /* apertura del semaforo mutex*/ if (-1 == (mutex = semOpen(claveMutex))) fprintf(stderr, "No tengo el cualificador de mutex\n"); /*apertura del semaforo bmutex*/ if (-1 == (bmutex = semOpen(bclaveMutex))) fprintf(stderr, "No tengo el cualificador de mutex\n"); /*Tratamiento de SUSTITUCION*/ do{ semWait(bmutex); caract =(*caracter); semSignal(mutex); switch(caract){ case '*': if(estado==INICIO){ estado=TRANSITO; }else{ fprintf(stdout, "^"); fflush(stdout); fprintf(fptsali,"^"); estado=INICIO; } break ; case EOF: break ; default: if(estado==INICIO) { fprintf(stdout,"%c",caract); fflush(stdout); fprintf(fptsali,"%c",caract); } else{ fprintf(stdout,"*%c",caract); fflush(stdout); fprintf(fptsali,"*%c",caract); estado=INICIO; } }/*fin del switch*/ } while (caract!=EOF); semClose(mutex); semClose(bmutex); fclose(fptsali); /* eliminar memoria compartida */ if(!eliminarMemoria()) fprintf(stderr, "Error al eliminar memoria compartida\n"); exit(0); }/*fin else proceso hijo */ }/*fin main()*/
![]()
Aquí el código fuente.
![]()
Fichero de cabecera con definiciones y declaraciones para usar memoria compartida.
#include <stdio.h> #include <time.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define ARRAY_SIZE 4000 #define MALLOC_SIZE 10000 #define SHM_SIZE 10000 #define SHM_MODE (SHM_R | SHM_W) /* read/write */ #define TRUE 1 #define FALSE 0 #ifdef RUTINAS_SHMEM static int shmid; /* handler de memoria compartida */ char *memoria; /* puntero a zona de memoria compartida */ #else extern char *memoria; #endif /* Prototipos de funciones de memoria compartida */ void origenTiempo(); void tiempoPasa(); int crearMemoria() ; int eliminarMemoria() ; #define TP tiempoPasa();
![]()
Aquí el código fuente.
Si quieres volver a la aproximación pincha aqui![]()
Si quieres volver a la aproximación pincha aqui![]()
Si quieres volver a la pincha aquí![]()