Sunteți pe pagina 1din 6

PROBLEMA PRODUCTOR CONSUMIDOR.

Cuando se comparten recursos en una PC, tal es el caso de un Buffer lo mas comn es que exista un proceso que se encargue de llenar el Buffer de informacin y otro proceso que saque informacin de este Buffer para procesarla, es en esta situacin donde se origina el problema del productor y consumidor, a continuacin se resolver este problema usando el mtodo de los semforos en lenguaje C.

>> Implantacin de semforos: #define N 100 /* nmero de ranuras en el buffer */ typedef int semaphore; /* los semforos son un tipo especial de int */ semaphore mutex = 1; /* controla el acceso a la regin crtica */ semaphore empty = N; /* cuenta ranuras vacas */ semaphore full = 0; /* cuenta ranuras completas */ >>Productor: producer() { int item; while (TRUE){ produce_item(&item); down(empty); down(mutex); enter_item(); up(mutex); up(full); } }

/* repetir indefinidamente */ /* generar el siguiente elemento */ /* disminuir el conteo vaco */ /* entrar en regin crtica */ /* colocar un elemento en el buffer */ /* salir de la regin crtica */ /* incrementar ranuras completas */

>> Consumidor: consumer() { int item; while (TRUE){

/* repetir indefinidamente */

produce_item(&item); down(full); down(mutex); remove_item(); up(mutex); up(empty); consume_item(); } }

/* generar el siguiente elemento */ /* disminuir el conteo completo */ /* entrar en regin crtica */ /* tomad un elemento del buffer */ /* salir de la regin crtica */ /* incrementar ranuras vacas */ /* hacer algo con el elemento */

Acontinuacion se presenta una idea de la solucion de este problema clasico usando contador de eventos que es una solucion alternativa a este problema tan conocido:

#include prototypes.h #define N 100 typedef int event_counter; event_counter in = 0; event_counter out = 0;

/*nmero de entradas en el almacn (buffer)*/ /*event_counter son un tipo especial de int*/ /*cuenta los elementos insertados en el almacn (buffer) */ /*cuenta los elementos retirados del almacn (buffer)*/

void producer(void) { int item, sequence = 0; while (TRUE) { sequence = sequence + 1; await(in, sequence);

/*ciclo infinito*/ /*nmero de elemento a eliminar del almacn (buffer)*/ /*espera a que est presente el elemento del

remove_item(&item); Advance(&out); consume_item(item) } }

espacio*/ /*retira al elemento de la entrada (sequence 1) % N */ /*deja que el productor se entere de que el elemento ha sido retirado*/ /*hace algo con el elemento*/

LA CENA DE LOS FILOSOFOS


#include #include #include #include #include #include /* Ejemplo 2.1 Programa para el problema de la cena de los filsofos. Cuando se invoca al programa se debe hacer con un argumento que indique el nmero de filsofos que queremos considerar. El programa debe reservar los recursos a compartir. Despus generar tantos filsofos como procesos hijos como se le halla indicado en el argumento. Como mximo se permitirn 10 procesos hijos compitiendo por los recursos para no sobrecargar el sistema. */ #define IZQ (i+nfil-1)%nfil #define DER (i+1)%nfil #define PENSANDO #define HAMBRE #define COMIENDO 0 1 2 /* Vecinos izquierdos de i */ /* Vecinos derechos de i */ <stdio.h> <unistd.h> <stdlib.h> <sys/ipc.h> <sys/shm.h> <sys/sem.h>

int nfil=5; /* Nmero de filsofos */ int shmid, /* Identificador de la memoria compartida */ semid; /* Identificador de los semaforos */ int *estado; /* Array para ver el estado de cada filsofo */ void sintaxis(void) { printf("Uso: filosofo <nmero>\n"); return; } void muestra_estados(void)

{ struct sembuf op; int i; op.sem_num=0; op.sem_op=-1; op.sem_flg=0; semop(semid, &op, 1);

/* down(&mutex); */

for(i=0;i<nfil;i++) printf("F0:%d ",estado[i]); printf("\n"); op.sem_num=0; op.sem_op=+1; op.sem_flg=0; semop(semid, &op, 1); } void probar(int i) { struct sembuf op; if(estado[i] == HAMBRE && estado[IZQ]!=COMIENDO && estado[DER]!=COMIENDO) { estado[i]=COMIENDO; op.sem_num=i+1; op.sem_op=1; op.sem_flg=0; semop(semid, &op, 1); } } void tomar_palillos(int i) { struct sembuf op; op.sem_num=0; op.sem_op=-1; op.sem_flg=0; semop(semid, &op, 1); estado[i]=HAMBRE; probar(i); op.sem_num=0; op.sem_op=+1; op.sem_flg=0; semop(semid, &op, 1); op.sem_num=i+1; op.sem_op=-1; op.sem_flg=0; semop(semid, &op, 1);

/* up(&mutex); */

/* up(&s[i]); */

/* down(&mutex); */

/* up(&mutex); */

/* down(&s[i]); */

} void dejar_palillos(int i) { struct sembuf op; op.sem_num=0; op.sem_op=-1; op.sem_flg=0; semop(semid, &op, 1); estado[i]=PENSANDO; probar(IZQ); probar(DER); op.sem_num=0; op.sem_op=+1; op.sem_flg=0; semop(semid, &op, 1); } void pensar(void) { muestra_estados(); sleep(1); /* Estan pensando un segundo */ } void comer(void) { /* muestro el nuevo estado de todos */ muestra_estados(); sleep(1); /* Estan comiendo un segundo */ } int main(int argc, char *argv[]) { int i,a; struct sembuf op; if(argc!=2) { sintaxis(); exit(0); } nfil=atoi(argv[1]); if(nfil<2 | nfil>10) { printf("Parmetro incorrecto\n"); printf("El nmero de filsofos debe estar entre 2 y 10\n"); sintaxis(); exit(0); } /* Primero reservamos los recursos */

/* down(&mutex); */

/* up(&mutex); */

/* Reservamos un arreglo compartido para ver el estado de cada uno este arreglo sustituye a la declaracin int estado[N] de Tanenbaum */ shmid=shmget(IPC_PRIVATE,nfil*sizeof(int), IPC_CREAT | 0600); if(shmid==-1) { perror("No pude reservar memoria compartida.\n"); exit(0); } /* Ahora reservamos un semforo para cada filsofo y uno ms para la exclusin mutua. Este ltimo es siempre el semforo nmero cero. */ semid=semget(IPC_PRIVATE, nfil+1, IPC_CREAT | 0600); if(semid==-1) { perror("No pude reservar los semaforos.\n"); exit(0); } /* Ponemos el mutex a uno */ op.sem_num=0; op.sem_op=1; op.sem_flg=0; semop(semid, &op, 1);

/* down(&mutex); */

/* Se crean nfil hijos */ for(i=0;i<nfil;i++) { a=fork(); switch(a) { case 0: /* Filsofo */ /* Es necesario que usemos la memoria compartida */ estado=(int *)shmat(shmid, 0, 0); while(1) /* A este habr que matarlo a mano con $killall filosofo */ { pensar(); /* Segn se crea que piense un rato */ tomar_palillos(i); comer(); dejar_palillos(i); } break; default: /* Creador de filsofos */ break; } } }

S-ar putea să vă placă și