在生产者-消费者情况下使用条件变量
我正在尝试了解条件变量以及如何在生产者-消费者的情况下使用它.我有一个队列,其中一个线程将数字推入队列,而另一个线程从队列中弹出数字.当生产线程放置一些数据时,我想使用条件变量向消费线程发出信号.问题是有时(或大多数时候)它只将最多两个项目推入队列然后挂起.我已经在 generate() 函数中指出它在调试模式下运行时停止的位置.谁能帮我指出为什么会这样?
I'm trying to learn about condition variables and how to use it in a producer-consumer situation. I have a queue where one thread pushes numbers into the queue while another thread popping numbers from the queue. I want to use the condition variable to signal the consuming thread when there is some data placed by the producing thread. The problem is there are times (or most times) that it only pushes up to two items into the queue then hangs. I have indicated in the produce() function where it stops when running in debug mode. Can anyone help me point out why this is happening?
我有以下全局变量:
boost::mutex mutexQ; // mutex protecting the queue
boost::mutex mutexCond; // mutex for the condition variable
boost::condition_variable condQ;
以下是我的消费者线程:
Below is my consumer thread:
void consume()
{
while( !bStop ) // globally declared, stops when ESC key is pressed
{
boost::unique_lock lock( mutexCond );
while( !bDataReady )
{
condQ.wait( lock );
}
// Process data
if( !messageQ.empty() )
{
boost::mutex::scoped_lock lock( mutexQ );
string s = messageQ.front();
messageQ.pop();
}
}
}
以下是我的制作人线程:
Below is my producer thread:
void produce()
{
int i = 0;
while(( !bStop ) && ( i < MESSAGE )) // MESSAGE currently set to 10
{
stringstream out;
out << i;
string s = out.str();
boost::mutex::scoped_lock lock( mutexQ );
messageQ.push( s );
i++;
{
boost::lock_guard lock( mutexCond ); // HANGS here
bDataReady = true;
}
condQ.notify_one();
}
}
推荐答案
您必须使用与在条件变量中使用的相同的互斥锁来保护队列.
You have to use the same mutex to guard the queue as you use in the condition variable.
这应该就是你所需要的:
This should be all you need:
void consume()
{
while( !bStop )
{
boost::scoped_lock lock( mutexQ);
// Process data
while( messageQ.empty() ) // while - to guard agains spurious wakeups
{
condQ.wait( lock );
}
string s = messageQ.front();
messageQ.pop();
}
}
void produce()
{
int i = 0;
while(( !bStop ) && ( i < MESSAGE ))
{
stringstream out;
out << i;
string s = out.str();
boost::mutex::scoped_lock lock( mutexQ );
messageQ.push( s );
i++;
condQ.notify_one();
}
}
相关文章