Título: Problema de semáforos con memoria compartida (Productor-Consumidor) Publicado por: hardcandy12 en 8 Febrero 2012, 17:49 pm Hola, tengo dificultades para resolver una modificación (especificada más abajo) de este problema en C para una máquina UNIX, y el problema es el siguiente:
Realizar un programa que implemente el problema del productor-consumidor con buffer circular utilizando semáforos y memoria compartida de la API System V. Para ello, utilizar como buffer una zona de memoria compartida (memoria principal) que contendrá N elementos (el tamaño del buffer será fijo y circular). Los procesos productor y consumidor se ejecutarán concurrentemente. Tener cuidado con la situación que se puede producir si termina la ejecución de un proceso antes de que comience a ejecutarse el otro ya que, en este caso, no existirá concurrencia e incluso puede dar algún error. Para solucionarlo hay distintas posibilidades. ¡Pensar en ello! DATOS: 1. El proceso productor se utilizará para generar las letras del abecedario y el proceso consumidor para mostrarlas en pantalla. 2. El proceso productor debe generar 200 letras 3. El tamaño del buffer debe ser de 15 elementos Este problema lo tengo resuelto y funciona y el código es el siguiente: //PROCESO PRODUCTOR #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define SEMKEY 110 #define SHMKEY 75 #define EM 0 //Semaforo de Exclusion Mutua #define EL 1 //Semáforo de Espacios Libres #define ED 2 //Semaforo de Elementos Disponibles int ed=0,el=0; int semid; char caracter=65; char carac[15]; struct sembuf sem_oper; // Para union semun { int val; struct semid_ds *semstat; unsigned short *array; } arg; void wait(int id) { sem_oper.sem_num=id; //actuamos sobre el semáforo id sem_oper.sem_op=-1; //decremento sem_oper.sem_flg=SEM_UNDO; // Para evitar interbloqueos semop(semid, &sem_oper,1); } void signal(int id) { sem_oper.sem_num=id; //actuamos sobre el semáforo id sem_oper.sem_op=1; //incremento sem_oper.sem_flg=SEM_UNDO; // Para evitar interbloqueos semop(semid, &sem_oper,1); } int main () { int n; int shmid[2]; char *addr, *buf; // Crear la región de memoria y obtener la dirección if((shmid[0] = shmget (SHMKEY, sizeof(char)*15, 0777 | IPC_CREAT))==-1){ printf("No se pudo reservar memoria"); exit(-1); } // Enlazar región al espacio de direccionamiento del proceso addr = shmat (shmid[0], 0, 0); buf = addr; //Reservar addr //crear 3 semáforos semid=semget(SEMKEY,3,0777|IPC_CREAT); // inicializar los semáforos arg.array=(unsigned short *) malloc(sizeof(short)*3); arg.array[0]=1; arg.array[1]=15; arg.array[2]=0; semctl (semid,3,SETALL,arg); // operamos sobre los semáforos for(n=1;n<=200;n++) { wait(EL); //ver si hay espacios libres wait(EM); // sección critica buf=addr; //Acceder a memoria compartida buf[el]=caracter; //escribir el caracter en memoria el=(el+1)%15; //actualizar el indice if(caracter=='Z') caracter='a'; //vuelve a empezar el abecedario else if(caracter=='z') //a z pase a A. caracter='A'; else caracter++; signal(EM); //salir de sc signal(ED); //actualizar los elementos disponibles } free(arg.array); // Separar la región del espacio de direccionamiento del proceso shmdt (addr); for(n=0;n<2;n++) shmctl(shmid[n],IPC_RMID,0); free(arg.array); return 0; } // fin del main //PROCESO CONSUMIDOR #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define SEMKEY 110 #define SHMKEY 75 #define EM 0 //Semaforo de Exclusion Mutua #define EL 1 //Semáforo de Espacios Libres #define ED 2 //Semaforo de Elementos Disponibles int ed=0; int semid; char caracter=200; char carac[15]; struct sembuf sem_oper; union semun { int val; struct semid_ds *semstat; unsigned short *array; } arg; void wait(int id) { sem_oper.sem_num=id; //actuar sobre el semáforo correspondiente sem_oper.sem_op=-1; //decremento 1 el semáforo sem_oper.sem_flg=SEM_UNDO; // Para evitar interbloqueos si un proceso acaba inesperadamente semop(semid, &sem_oper,1); } void signal(int id) { sem_oper.sem_num=id; //actuar sobre el semáforo correspondiente sem_oper.sem_op=1; //incremento sem_oper.sem_flg=SEM_UNDO; // Para evitar interbloqueos semop(semid, &sem_oper,1); } int main () { int eof; int n; int shmid[2]; char *addr, *buf; //Crear la región de memoria y obtener la dirección if((shmid[0] = shmget (SHMKEY, sizeof(char)*15, 0777 | IPC_CREAT))==-1){ printf("No se pudo reservar memoria"); exit(-1); } //Enlazar región al espacio de direccionamiento del proceso addr = shmat (shmid[0], 0, 0); if((shmid[1] = shmget (SHMKEY, sizeof(int), 0777 | IPC_CREAT))==-1){ printf("No se pudo reservar memoria"); exit(-1); } // Enlazar región al espacio de direccionamiento del proceso eof = shmat (shmid[1], 0, 0); //creación de 3 semáforos semid=semget(SEMKEY,3,0777|IPC_CREAT); // inicialización de los semáforos arg.array=(unsigned short *) malloc(sizeof(short)*3); arg.array[0]=1; arg.array[1]=15; arg.array[2]=0; semctl (semid,3,SETALL,arg); // operamos sobre los semáforos for(n=1;n<=200;n++) // 200 caracteres { wait(ED); //Comprobar que hay elementos disponibles wait(EM); // sección critica buf=addr; //acceder a memoria compartida caracter=buf[ed]; //leer el caracter printf("%c",caracter); //imprimir por pantalla ed=(ed+1)%15; //actualizar el indice signal(EM); //salir de sección critica signal(EL); //actualizar los espacios libres } semctl (semid,3,IPC_RMID,0); // Separar la región del espacio de direccionamiento del proceso shmdt (addr); shmdt (eof); for(n=0;n<2;n++) shmctl(shmid[n],IPC_RMID,0); free(arg.array); return 0; } // fin del main Ahora tengo que hacer una modificación y tengo dificultades para hacerlo, y el problema es el siguiente: Modificar el ejercicio básico anterior para que el proceso productor en lugar de generar letras del abecedario, pida por teclado el nombre de un archivo (cuyo contenido sea texto en ASCII) e introduzca su contenido en el buffer y el proceso consumidor lo mostrará en pantalla. Se debe seguir respectando el tamaño del buffer. Ayudenme a resolverlo por favor, un saludo. Título: Re: Problema de semáforos con memoria compartida (Productor-Consumidor) Publicado por: Akai en 8 Febrero 2012, 19:31 pm Aquí no realizamos tareas, ejercicios etc etc etc...
En cambio, si lo intentas y tienes dudas, si te podemos ayudar, pero hacerlo por ti: NO Título: Re: Problema de semáforos con memoria compartida (Productor-Consumidor) Publicado por: hardcandy12 en 9 Febrero 2012, 23:58 pm Aquí no realizamos tareas, ejercicios etc etc etc... En cambio, si lo intentas y tienes dudas, si te podemos ayudar, pero hacerlo por ti: NO Lo he intentado y claro que tengo dudas y problemas a la hora de resolverlo, o esk no has leido lo que escribi arriba, y he pedido que me ayuden a resolverlo, no a que me lo hagan, puesto que la gran parte del ejercicio la he resuelto yo y solo tengo problemas con una modificacion del ejercicio, asike si me kieres ayudar lo dices y si no, no tienes porke decir lo que tengo que hacer yo o lo que tiene que hacer la gente. Título: Re: Problema de semáforos con memoria compartida (Productor-Consumidor) Publicado por: Eternal Idol en 10 Febrero 2012, 00:29 am No se hacen tareas.
|