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