class MyClass
{
public:
void PushMessage(MyMessage m) // Thread 1 calls this
开发者_Go百科 {
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;
};
When I run the code, PushMessage
is called, and foo()
is waiting on PopMessage()
, but PopMessage
never returns.
What does do_something
here is not irrelevant I think.
What am I doing wrong here? Strangely, the above code worked fine under mac, but I'm having trouble on linux.
boost version is 1.44.0Thank you
Rather than letting the scope of the lock object expire before it unlocks, you could try to manually unlock the mutex in PushMessage()
before you unblock the waiting thread, i.e.,
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();
}
That way when thread 2 unblocks, there will be no "cross-over" time where thread 1 contains the lock, and thread 2 is trying to obtain a lock on your mutex. I don't see why that would create problems, but again, at least you won't have thread 2 trying to call lock.lock()
while thread 1 still contains the lock.
I think you need 2 mutex objects, one is for synchronizing method call in different threads, one is for condition wait. You mixed them.
精彩评论