What is the reason for a notified condition variable to re-lock the mutex after being notified.
The following piece of code deadlock if unique_lock is not scoped or if mutex is not explicitely unlocked
#include <future>
#include <mutex>
#include <iostream>
using namespace std;
int main()
{
std::mutex mtx;
std::condition_variable cv;
//simulate another working thread sending notification
auto as = std::async([&cv](){ std::this_thread::sleep_for(std::chrono::seconds(2));
cv.notify_all();});
//uncomment scoping (or unlock below) to prevent deadlock
//{
std::unique_lock<std::mutex> lk(mtx);
//Spurious Wake-Up Prevention not adressed in this short sample
//UNLESS it is part of the answer / reason to lock again
cv.wait(lk);
//}
std::cout << "CV notified\n" << std::flush;
//uncomment unlock (or scoping above) to prevent deadlock
//mtx.unlock();
mtx.lock();
//do something
mtx.unlock();
std::cout << "End may never be reached\n" << std::flush;
return 0;
}
Even re-reading some documentation and examples I still do not find this obvious.
Most examples that can be found over the net are small code samples that have inherent scoping of the unique_lock.
Shall we use different mutex to deal with critical sections (mutex 1) and condition variables wait and notify (mutex 2) ?
Note: Debug shows that after end of the waiting phase, the "internal" "mutex count" (I think field __count of structure __pthread_mutex_s ) goes from 1 to 2. It reaches back 0 after unlock