提升互斥,条件,scoped_lock,我在这里使用它们错了吗?

时间:2011-05-07 05:24:29

标签: c++ boost mutex

class MyClass
{
public:
    void PushMessage(MyMessage m) // Thread 1 calls this
    {
        boost::mutex::scoped_lock lock(mMutex);
        mQueue.push_back(m);
        mCondition.notify_one();
    }

    MyMessage PopMessage()
    {
        boost::mutex::scoped_lock lock(mMutex);
        while(mQueue.empty())
            mCondition.wait(lock);

        MyMessage message = mQueue.front();
        mQueue.pop_front();
        return message;
    }

    void foo() // thread 2 is running this loop, and supposed to get messages
    {
        for(;;)
        {
            MyMessage message = PopMessage();

            do_something(message);
        }
    }
private:
    std::deque<MyMessage> mQueue;

    boost::mutex mMutex;
    boost::condition mCondition;
};

当我运行代码时,PushMessage被调用,而foo()正在等待PopMessage(),但PopMessage永远不会返回。

我认为这里的do_something与我无关。

我在这里做错了什么? 奇怪的是,上面的代码在mac下运行良好,但我在linux上遇到了麻烦 提升版本是1.44.0

谢谢

2 个答案:

答案 0 :(得分:1)

您可以尝试在解锁等待线程之前手动解锁PushMessage()中的互斥锁,而不是让锁定对象的范围在解锁之前到期,即

void PushMessage(MyMessage m) // Thread 1 calls this
{
    boost::mutex::scoped_lock lock(mMutex);
    mQueue.push_back(m);

    lock.unlock(); // <== manually unlock

    mCondition.notify_one();
}

这样当线程2解除阻塞时,线程1将包含锁定,并且线程2试图获取互斥锁的锁定时,将没有“交叉”时间。我不明白为什么会产生问题,但同样,至少你不会让线程2尝试调用lock.lock()而线程1仍然包含锁。

答案 1 :(得分:-2)

我认为你需要2个互斥对象,一个用于在不同的线程中同步方法调用,一个用于条件等待。你混合了它们。