1
votes

Example code from std::condition_variable::notify_one.

My question is:
Is it possible for a notifying thread to lock, before the notified thread's wait function to lock, since the notify operation does not block current thread?


Code: (I delete the original comments)

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>

std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;

void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cout << "Waiting... \n";
    cv.wait(lk, []{return i == 1;}); //Waiting 
    std::cout << "...finished waiting. i == 1\n";
    done = true;
}

void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Notifying falsely...\n";
    cv.notify_one(); //Notifying

    std::unique_lock<std::mutex> lk(cv_m);//Is it possible for this line to execute
                                         //before cv.waits() in waits() tries to lock ?
    i = 1;
    while (!done)
    {
        std::cout << "Notifying true change...\n";
        lk.unlock();
        cv.notify_one(); 
        std::this_thread::sleep_for(std::chrono::seconds(1));
        lk.lock();
    }
}

int main()
{
    std::thread t1(waits), t2(signals);
    t1.join();
    t2.join();
}
1
Yes, it is possible to lock by notifying thread before the waiting one. But how does it make the code unsafe?bartop
@bartop Yes, you are right.. It won't make the code unsafe even so. Btw, is there any rules that gurantee the execution order? Or it is simply undefined?Rick

1 Answers

0
votes

In answer to your title question, yes. It is possible that the signals thread locks prior to the waits thread. But in answer to your real question, no, this won't cause a deadlock.

Why?

Because further in the example the mutex is released by lk.unlock(). At this unlock the waits thread will have an opportunity to lock (then unlock again when waiting begins).

This loop continues until the wait thread has signified it is completed with the done boolean.

An example timing:

enter image description here

There are plenty of others, but in all cases the relevant objects and condition variables are protected by the mutex. You can't have data races or deadlocks. This example is sound.