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
谢谢
答案 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个互斥对象,一个用于在不同的线程中同步方法调用,一个用于条件等待。你混合了它们。