Skip to content

Instantly share code, notes, and snippets.

@rolandostar
Created June 1, 2016 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rolandostar/8116af410d170a15a49ee041e01cd63a to your computer and use it in GitHub Desktop.
Save rolandostar/8116af410d170a15a49ee041e01cd63a to your computer and use it in GitHub Desktop.
#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