【问题标题】:boost mutex, condition, scoped_lock , am I using them wrong here?boost mutex, condition, scoped_lock ,我在这里用错了吗?
【发布时间】:2011-05-07 05:24:29
【问题描述】:
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

谢谢

【问题讨论】:

  • 什么是do_something?谁打电话给PushMessage?这段代码充其量是不完整的。
  • 线程库中没有boost::condition。你的意思是boost::condition_variable?正如所写的那样,通过该修复程序,您的代码在带有 boost 1.42 和 boost 1.46(手头没有 1.44)的 linux 上运行,并且没有显示您描述的问题。

标签: c++ boost mutex


【解决方案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 仍然包含锁。

【讨论】:

  • 我最近了解到这实际上比看起来更复杂,这里是链接:domaigne.com/blog/computing/… 有这样一个东西wait morphing 优化,它可以防止你谈论的问题。当使用超过 2 个线程时,在锁定时通知将使整个程序更安全。
【解决方案2】:

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

【讨论】:

  • 我认为这是不正确的。互斥锁应该保护信号/等待和条件设置/条件检查。在这种情况下,条件是mQueue.empty(),因此队列应该受到同一个互斥体的保护。
猜你喜欢
  • 2011-01-17
  • 1970-01-01
  • 2011-02-22
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多