#ifndef SYNCLIST_H #define SYNCLIST_H #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <string.h> struct synclist { int max_size; int max_string_size; char **element; pthread_mutex_t mutex; pthread_cond_t read_done,write_done; int size; }; void synclist_init(struct synclist *o, int max_size,int max_string_size) { int i; pthread_mutex_init(&o->mutex,NULL); pthread_cond_init(&o->read_done,NULL); pthread_cond_init(&o->write_done,NULL); o->max_size = max_size; o->max_string_size = max_string_size; o->element = (char **)malloc(o->max_size*sizeof(char *)); for(i=0;i<o->max_size;i++) { o->element[i] = (char *)malloc(o->max_string_size*sizeof(char)); } o->size = 0; } void synclist_destroy(struct synclist *o) { int i; pthread_mutex_lock(&o->mutex); pthread_mutex_destroy(&o->mutex); pthread_cond_destroy(&o->read_done); pthread_cond_destroy(&o->write_done); for(i=0;i<o->max_size;i++) { free(o->element[i]); } free(o->element); } void synclist_push(struct synclist *o,char *element) { pthread_mutex_lock(&o->mutex); while ( o->size >= (o->max_size) ) { /* List is full, waiting for read_done */ pthread_cond_wait(&o->read_done,&o->mutex); } /* Write and unlock */ strncpy(o->element[o->size],element,o->max_string_size); o->size++; pthread_cond_signal(&o->write_done); pthread_mutex_unlock(&o->mutex); } void synclist_pop(struct synclist *o,char *element) { pthread_mutex_lock(&o->mutex); while ( o->size <= 0 ) { /* Empty list, waiting for write_done */ pthread_cond_wait(&o->write_done,&o->mutex); } /* Read and unlock */ strncpy(element,o->element[o->size-1],o->max_string_size); o->size--; pthread_cond_signal(&o->read_done); pthread_mutex_unlock(&o->mutex); } #endif
A su vez, meterlo todo en la cabecera synclist.h y a continuación emplearla desde por ejemplo:
#include "synclist.h" #include <stdio.h> #define LIST_SIZE 10 #define BUFFER_SIZE 1024 #define READERS 5 void *writer(void *mysl) { int counter = 0; char msg[BUFFER_SIZE]; struct synclist *sl; sl = (struct synclist *)mysl; while ( 1 ) { sprintf(msg,"message #%d",counter); counter++; synclist_push(sl,msg); printf("Writing msg %s (list size %d) (thread id %d)\n", msg,sl->size,abs((unsigned int)pthread_self())); fflush(stdout); } } void *reader(void *mysl) { char msg[BUFFER_SIZE]; struct synclist *sl; sl = (struct synclist *)mysl; while ( 1 ) { synclist_pop(sl,msg); printf("Reading msg %s (list size %d) (thread id %d)\n", msg,sl->size,abs((unsigned int)pthread_self())); fflush(stdout); } } int main(int argc,char *argv[]) { struct synclist sl; char buffer[BUFFER_SIZE]; pthread_t t[READERS+1]; int i; synclist_init(&sl,LIST_SIZE,BUFFER_SIZE); pthread_create(&t[0],NULL,writer,(void *)&sl); for(i=0;i<READERS;i++) { pthread_create(&t[i+1],NULL,reader,(void *)&sl); } while ( 1 ) { continue; } synclist_destroy(&sl); return 0; }
No hay comentarios:
Publicar un comentario