[英]How to synchronize threads (consumer/producer)
I have the 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 and then wait for signal to 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 is example works fine when consumer thread takes the mutex first. 当使用者线程首先使用互斥锁时,此示例工作正常。 But then when the producer thread acquires the mutex initially at first, I will always have 1 integer in the queue that the consumer can't pop.
但是,当生产者线程最初最初获取互斥量时,队列中将始终有1个整数,消费者无法弹出该整数。
How can I let the consumer thread, initially acquire the mutex before the producer. 我如何让使用者线程在产生者之前先获取互斥体。
Note: I am looking for a better way than launching one thread before the other. 注意:我正在寻找一种比在另一个线程之前启动一个线程更好的方法。
Thanks, 谢谢,
One problem I see is that your consumer doesn't actually check for work to do, it just blindly pops from the queue. 我看到的一个问题是,您的消费者实际上并没有检查要完成的工作,只是从队列中盲目弹出。
The second problem I see is that you increment count in one and decrement it in the other, so how do you ever reach the termination condition? 我看到的第二个问题是您在一个中增加计数而在另一个中减少计数,那么您如何达到终止条件?
Take the ninja "count--" out of consumer and it should work. 将忍者“计数-”从消费者中删除,它应该可以工作。 Still, you might want to do the following inside consumer:
不过,您可能想在使用者内部执行以下操作:
// Wait for producer to do its thing and tell us there is work to do.
while ( myqueue.empty() ) {
pthread_cond_wait(&condition_var, &count_mutex);
}
// we've been told there's work to do with the queue,
// and we know there's something ON the queue.
// consume the entire queue.
while ( !myqueue.empty() ) {
myqueue.pop();
}
// treat count as protected by the mutex, so hoist this test into the 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 and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
// Wait for producer to do its thing and tell us there is work to do.
while ( myqueue.empty() )
pthread_cond_wait( &condition_var, &count_mutex );
// we've been told there's work to do with the queue,
// and we know there's something ON the queue.
// consume the entire queue.
while ( myqueue.empty() == false ) {
myqueue.pop();
}
// count is protected by the lock so check if we're done before we unlock.
workDone = (count >= COUNT_DONE);
pthread_mutex_unlock( &count_mutex );
}
return NULL;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.