-
-
Save rolandostar/8116af410d170a15a49ee041e01cd63a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <errno.h> | |
#include <sys/types.h> | |
#include <sys/sem.h> | |
#include <sys/types.h> | |
#include <sys/ipc.h> | |
#include <sys/shm.h> | |
#include <unistd.h> | |
#define CONSUMIDOR 2 | |
#define PRODUCTOR 1 | |
#define END 23 | |
#define RANURAS 5 // Cada Torre | |
#define CANT 20 // Cada hilo | |
int control; | |
struct slot { | |
int tipo; | |
char destino[10]; | |
char mensaje[20]; | |
int banderaL; | |
}; | |
void wait(int who,int size){ | |
struct sembuf operacion; | |
operacion.sem_num = who; | |
operacion.sem_op = -size; | |
operacion.sem_flg = SEM_UNDO; | |
semop(control, &operacion, 1 ); | |
} | |
void signal(int who, int size){ | |
struct sembuf operacion; | |
operacion.sem_num = who; | |
operacion.sem_op = size; | |
operacion.sem_flg = SEM_UNDO; | |
semop(control, &operacion, 1 ); | |
} | |
void *produceL(void *i_void_ptr){ | |
struct slot *torre1 = (struct slot*)i_void_ptr; | |
int conteo=0,k; | |
char buffer[20]; | |
for(size_t g=0;g<CANT;g++){ // Numero de Llamadas a producir | |
k=-1; | |
wait(PRODUCTOR,1); | |
while(1){ // Este es el barrido de todas las ranuras. | |
k = (k+1)%RANURAS; // %n numero de ranuras que existen | |
printf("%d: ",k); | |
if(torre1[k].banderaL) printf("Lleno: %s\n",torre1[k].mensaje); | |
else{ | |
printf("Vacio, Llenando...\n"); | |
sprintf(buffer,"Llamada N:%d",conteo++); | |
strcpy(torre1[k].mensaje,buffer); | |
torre1[k].banderaL = 1; | |
signal(CONSUMIDOR,1); | |
break; // El final es cuando ha producido un mensaje | |
} | |
} | |
printf("=============================\n"); // Termina 1 operacion y continua hasta producir CANT | |
} | |
pthread_exit(0); | |
} | |
void *produceM(void *i_void_ptr){ | |
struct slot *torre1 = (struct slot*)i_void_ptr; | |
int conteo=0,k; | |
char buffer[20]; | |
for(size_t g=0;g<CANT;k=-1,g++){ | |
k=-1; | |
wait(PRODUCTOR,1); | |
while(1){ | |
k = (k+1)%RANURAS; | |
printf("%d: ",k); | |
if(torre1[k].banderaL) printf("Lleno: %s\n",torre1[k].mensaje); | |
else{ | |
printf("Vacio, Llenando...\n"); | |
sprintf(buffer,"Mensaje N:%d",conteo++); | |
strcpy(torre1[k].mensaje,buffer); | |
torre1[k].banderaL = 1; | |
signal(CONSUMIDOR,1); | |
break; | |
} | |
} | |
printf("=============================\n"); | |
} | |
pthread_exit(0); | |
} | |
/* | |
void *produceM(){ | |
int conteo=0; | |
for(size_t g=0;g<5;g++){ | |
sprintf(buffer,"Mensaje N:%d",conteo++); | |
strcpy(torre1[g].mensaje,buffer); | |
} | |
} | |
*/ | |
int main(){ | |
int shmid_1,shmid_2,clean; | |
struct slot *torre1,*torre2; | |
key_t key_1=1111; // Uno a Uno y semaphoros | |
key_t key_2=5151; // Bulk | |
pthread_t llamadas,mensajes; | |
if ((shmid_1 = shmget(key_1, 20 * sizeof(struct slot), IPC_CREAT | 0666)) < 0) { // Crea/Recupera Memoria -> shmid_1 | |
perror("shmget"); | |
exit(1); | |
} | |
if ((torre1 = shmat(shmid_1, NULL, 0)) == (struct slot*)-1) { //Mapea memoria a local -> torreX | |
perror("shmat"); | |
exit(1); | |
} | |
if ( (control = semget(key_1, 23, IPC_CREAT | 0600)) < 0 ) { // Crea/Recupera Semaforo -> control | |
perror("Error SEMGET\n"); | |
exit(-1); | |
} | |
if(semctl(control,0,GETVAL,NULL)==0){ | |
printf("Me ejecute primero, inicializando semaforos... Valor:%d\n",semctl(control,0,GETVAL,NULL)); | |
semctl(control, CONSUMIDOR, SETVAL, 0); | |
semctl(control, END, SETVAL, 0); | |
semctl(control, PRODUCTOR, SETVAL, RANURAS); | |
signal(0,1); | |
} | |
if(pthread_create(&llamadas, NULL, produceL,(void*)torre1)) { | |
fprintf(stderr, "Error creating thread\n"); | |
return 1; | |
} | |
if(pthread_create(&mensajes, NULL, produceM,(void*)torre1)) { | |
fprintf(stderr, "Error creating thread\n"); | |
return 1; | |
} | |
/* | |
if(pthread_create(&mensajes, NULL, decinc_x,&i)) { | |
fprintf(stderr, "Error creating thread\n"); | |
return 1; | |
} | |
*//* | |
for (int g = 0; g < 3; g++) { | |
sprintf(buffer,"Ejecucion N:%d",g); | |
strcpy(torre1[g].mensaje,buffer); | |
printf("Enviando señal a productor...\n"); | |
signal(PRODUCTOR,1); | |
//wait(CONSUMIDOR, globales[0]); | |
//printf("%i .- Consumidor\n", globales[1]); | |
//signal(PRODUCTOR, globales[0]); | |
} | |
/* | |
if(semget(key, 2, 0600) >= 0){ // Cleanup | |
printf("\nCLEANUP: Semaforo y Memoria Liberados\n"); | |
if (semctl(globales[0], 0, IPC_RMID, NULL) == -1) { | |
perror("semctl"); | |
exit(1); | |
} | |
shmctl(shmid, IPC_RMID, 0); | |
} | |
*/ | |
if(pthread_join(llamadas, NULL)) { | |
fprintf(stderr, "Error joining thread\n"); | |
return 2; | |
} | |
if(pthread_join(mensajes, NULL)) { | |
fprintf(stderr, "Error joining thread\n"); | |
return 2; | |
} | |
printf("Esperando Final...\n"); | |
wait(END,1); | |
printf("Final Recibido. Terminando.\n"); | |
if(semget(key_1, 2, 0600) >= 0){ // Cleanup | |
printf("\nCLEANUP: Semaforo y Memoria Liberados\n"); | |
if (semctl(control, 0, IPC_RMID, NULL) == -1) perror("semctl - cleanup"); | |
if (shmctl(shmid_1, IPC_RMID, 0) == -1) perror("shmctl - 1"); | |
//if (shmctl(shmid_2, IPC_RMID, 0) == -1) perror("shmctl - 2"); | |
} | |
shmdt(&shmid_1); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment