在生产者 - 消费者情境中使用条件变量

时间:2010-03-04 14:05:53

标签: c++ boost multithreading condition-variable

我正在尝试了解条件变量以及如何在生产者 - 消费者情况下使用它。我有一个队列,其中一个线程将数字推入队列,而另一个线程从队列中弹出数字。我希望在生产线程放置一些数据时使用条件变量来指示消费线程。问题是有时(或大多数时候)它只将两个项目推入队列然后挂起。我在produce()函数中指出它在调试模式下运行时停止。任何人都可以帮我指出为什么会这样吗?

我有以下全局变量:


boost::mutex mutexQ;               // mutex protecting the queue
boost::mutex mutexCond;            // mutex for the condition variable
boost::condition_variable condQ;

以下是我的消费者主题:


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();
        }
    }
}

以下是我的制作人主题:


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();
    }
}

1 个答案:

答案 0 :(得分:36)

在条件变量中使用时,必须使用相同的互斥锁来保护队列。

这应该是你所需要的:

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();
    }
}