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
 
     
     
    