I'm having a dead-lock when trying to notify a condition_variable from a thread.
Here is my MCVE:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
static boost::mutex m_mutex;
static boost::condition_variable m_cond;
void threadFunc()
{
std::cout << "LOCKING MUTEX" << std::endl;
boost::mutex::scoped_lock lock( m_mutex );
std::cout << "LOCKED, NOTIFYING CONDITION" << std::endl;
m_cond.notify_all();
std::cout << "NOTIFIED" << std::endl;
}
int main( int argc, char* argv[] )
{
while( true )
{
std::cout << "TESTING!!!" << std::endl;
boost::mutex::scoped_lock lock( m_mutex );
boost::thread thrd( &threadFunc );
//m_cond.wait( lock );
while ( !m_cond.timed_wait(lock,boost::posix_time::milliseconds(1)) )
{
std::cout << "WAITING..." << std::endl;
}
static int pos = 0;
std::cout << "DONE!!! " << pos++ << std::endl;
thrd.join();
}
return 0;
}
If using m_cond.wait( lock );, I see DONE!!! being written for every attempt, no problem here.
If I use the while ( !m_cond.timed_wait(lock,boost::posix_time::milliseconds(1)) ) loop, I see DONE!!! being written for a few attempts, and, at some point, I get a dead lock and waiting finally never ends:
TESTING!!!
LOCKING MUTEX
LOCKED, NOTIFYING CONDITION
NOTIFIED
WAITING...
WAITING...
WAITING...
WAITING...
WAITING...
WAITING...
...
I have read other posts on stackoverflow (like Condition variable deadlock): they mention that this could happen if notify_all is called before condition's wait function is running, so the mutex must be used to prevent that. But I feel like that's what I'm doing:
- I lock the mutex before creating the thread
- Then thread cannot notify before
m_cond.timed_waitis reached (and then mutex is unlocked) - Within the loop, in case of timeout,
timed_waitrelocks the mutex so notify cannot be done, we print "WITTING..." and we release the mutex when we are again ready to receive the notification
So why is the dead-lock occuring? Could the condition be notified between the moment when timed_wait detects the timeout and relock the mutex?