Bound Conditional predicate blocks child thread

42 views Asked by At

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?

1

There are 1 answers

2
Surt On BEST ANSWER

The first time through the worker loop you have the lock, the 2nd time you don't have the lock.

Wait until notified

The execution of the current thread (which shall have locked lck's mutex) is blocked until notified.

It needs to be locked.

printf("Start worker thread. \n");
while (true) {
    printf("Inside while loop and waiting. \n");
    std::unique_lock<std::mutex> ul(m_mutex);
    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();
}

This should improve you chance of getting it right.