Boost mutex, condition, scoped_lock, am I using them here incorrectly?

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

When I run the code, PushMessage is PushMessage and foo() expects PopMessage() , but PopMessage never returns.

What do_something here doesn't matter.

What am I doing wrong here? Oddly enough, the above code worked fine for Mac, but I have problems with Linux.
accelerated version - 1.44.0

thanks

+4
source share
2 answers

Instead of letting the lock object expire before it unlocks, you can try manually unlocking the mutex in PushMessage() before unlocking 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(); } 

Thus, when thread 2 is unlocked, there will be no β€œcross” time when thread 1 contains a lock, and thread 2 tries to get a lock on your mutex. I do not understand why this would create problems, but again, at least you will not have thread 2 trying to call lock.lock() , while thread 1 still contains the lock.

+1
source

It seems to me that you need two mutex objects, one for synchronizing a method call in different threads, one for a wait condition. You mixed them.

-2
source

All Articles