I am trying to create a thread that gets notified via the Conditional variable to execute some code. I bounded the thread to a class member function like this:
m_dbSaver = std::thread(std::bind(&ContactLearningApp::DBWorkerThread, this));
m_lk = std::unique_lock<std::mutex>(m_mutex);
m_Processed = true;
Every half a second, I try to run the thread like this:
if (m_sampleClock.getTimeMilliseconds() > 500) {
printf("Save samples to DB\n");
// Wait for worker to finish processing
m_cv.wait(m_lk, [this] {return this->m_Processed; });
// Instruct thread to execute
m_Ready = true;
m_cv.notify_one();
m_sampleClock.reset();
}
My Worker thread looksl ike this:
void ContactLearningApp::DBWorkerThread() {
std::unique_lock<std::mutex> ul(m_mutex);
printf("Start worker thread. \n");
while (true) {
printf("Inside while loop and waiting. \n");
m_cv.wait(ul, [this] {return this->m_Ready; });
printf("Condition passed. \n");
m_Processed = false;
std::cout << "Worker thread processing data. " << std::endl;
m_Processed = true;
ul.unlock();
m_cv.notify_one();
}
}
The worker thread never passes the condition even though I set the m_Ready predicate to be true. If I set the m_Ready variable to be true before I create the thread, the condition passes. Am I doing this correctly?
The first time through the worker loop you have the lock, the 2nd time you don't have the lock.
It needs to be locked.
This should improve you chance of getting it right.