c - pthread synchronization on two consumers one producer -
i have worker thread processing queue of work items.
//producer void push_into_queue(char *item) { pthread_mutex_lock (&queuemutex); if(workqueue.full) { // full } else{ add_item_into_queue(item); pthread_cond_signal (&queuesignalpush); } pthread_mutex_unlock(&queuemutex); } // consumer1 void* worker(void* arg) { while(true) { pthread_mutex_lock(&queuemutex); while(workqueue.empty) pthread_cond_wait(&queuesignalpush, &queuemutex); item = workqueue.front; // pop queue add_item_into_list(item); // need signal here thread2? pthread_cond_signal(&queuesignalpop); pthread_mutex_unlock(&queuemutex); } return null; } pthread_create (&thread1, null, (void *) &worker, null); now have thread2 consume data inserted in add_item_into_list() if items have been added list. note list permanent , can't emptied nor freed entire duration of program.
so question is: need pthread_cond_signal?, if yes, signal go? , how other worker (canonical form)?
i see 2 possible ways of solving problem:
a. introduce condition variable (e.g. signallist) list, consumer2 thread wait events on it. in case consumer1 have signal twice: once on queuesignalpop , once on signallist:
// consumer1 void* worker(void* arg) { while(true) { // ... pthread_cond_signal(&queuesignalpop); pthread_cond_signal(&signallist); pthread_mutex_unlock(&queuemutex); } return null; } b. use existing condition queuesignalpop variable inside consumer2 wait events, , use broadcast instead of signal inside consumer1. broadcast means waiting threads on condition variable wake up:
// consumer1 void* worker(void* arg) { while(true) { // ... pthread_cond_broadcast(&queuesignalpop); pthread_mutex_unlock(&queuemutex); } return null; } // consumer2 void* worker2(void* arg) { while(true) { while(list.empty) pthread_cond_wait(&queuesignalpop, &queuemutex); // ... } return null; } i propose go first approach, since better distinguish purpose of each condition variable.
Comments
Post a Comment