c++ - How to synchronize threads (consumer/producer) -
i have following code:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <queue> using namespace std; queue<int> myqueue; pthread_mutex_t count_mutex = pthread_mutex_initializer; pthread_cond_t condition_var = pthread_cond_initializer; void *consumer(void*); void *producer(void*); #define count_done 10 int count = 0; main() { pthread_t thread1, thread2; pthread_create( &thread2, null, &consumer, null); pthread_create( &thread1, null, &producer, null); pthread_join( thread1, null); pthread_join( thread2, null); printf("final count: %d\n",count); system("pause"); return exit_success; } void *consumer(void*) { for(;;) { // lock mutex , wait signal relase mutex printf("consumer mutex lock \n"); pthread_mutex_lock( &count_mutex ); printf("consumer mutex locked\n"); // wait while functioncount2() operates on count // mutex unlocked if condition varialbe in functioncount2() signaled. printf("consumer wait\n"); pthread_cond_wait( &condition_var, &count_mutex ); printf("consumer condition woke up\n"); myqueue.pop();count--; printf("counter value consumer: %d\n",count); printf("consumer mutex unlock\n"); pthread_mutex_unlock( &count_mutex ); if(count >= count_done) return(null); } } void * producer(void*) { for(;;) { printf("producer mutex lock\n"); pthread_mutex_lock( &count_mutex ); printf("producer mutex locked\n"); if( count < count_done) { myqueue.push(1); count++; printf("counter value producer: %d\n",count); printf("producer signal\n"); pthread_cond_signal( &condition_var ); } printf("producer mutex unlock\n"); pthread_mutex_unlock( &count_mutex ); if(count >= count_done) return(null); sleep(5000); } }
this example works fine when consumer thread takes mutex first. when producer thread acquires mutex @ first, have 1 integer in queue consumer can't pop.
how can let consumer thread, acquire mutex before producer.
note: looking better way launching 1 thread before other.
thanks,
one problem see consumer doesn't check work do, blindly pops queue.
the second problem see increment count in 1 , decrement in other, how ever reach termination condition?
take ninja "count--" out of consumer , should work. still, might want following inside consumer:
// wait producer thing , tell there work do. while ( myqueue.empty() ) { pthread_cond_wait(&condition_var, &count_mutex); } // we've been told there's work queue, // , know there's on queue. // consume entire queue. while ( !myqueue.empty() ) { myqueue.pop(); } // treat count protected mutex, hoist test lock. bool workdone = (count >= count_done); pthread_mutex_unlock(&count_mutex); if(workdone) return break;
edit: preferred version of consumer:
bool workdone = false; while(workdone == false) { // lock mutex , wait signal relase mutex pthread_mutex_lock( &count_mutex ); // wait producer thing , tell there work do. while ( myqueue.empty() ) pthread_cond_wait( &condition_var, &count_mutex ); // we've been told there's work queue, // , know there's on queue. // consume entire queue. while ( myqueue.empty() == false ) { myqueue.pop(); } // count protected lock check if we're done before unlock. workdone = (count >= count_done); pthread_mutex_unlock( &count_mutex ); } return null;
Comments
Post a Comment