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();
}
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:
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.