C++ condition variable ~ 96% (also explaining how condition_variable works)
How condition_variable works:\n1. First, you need to acquire a mutex using unique_lock. We need a unique_lock because before putting the thread to sleep, condit
How `condition_variable` works:\n1. First, you need to acquire a `mutex` using `unique_lock`. We need a unique_lock because before putting the thread to sleep, condition_variable will need to release the mutex and unique_lock provides that flexibility.\n2. Next, you call the `wait` function of condition_variable with the above lock and optionally a `predicate`. It causes the current thread to block (sleep). The thread is unblocked when `notify_all` or `notify_one` is executed on some other thread. \n4. It might also be unblocked *spuriously* that\'s where the predicate comes handy. So, whenever there are spurious wake-ups, condition_variable will acquire the mutex and check the predicate. **If** the predicate returns true, thread will proceed further and mutex will stay acquired, **otherwise** it will release the mutex and sleep again.\n5. When the thread has completed its work, it\'s *generally* a better idea to release the lock before notifying other threads, if need be.\n\n```\nclass Foo {\npublic:\n    void first(function<void()> printFirst) {\n        // first doesn\'t have to wait for anyone and it doesn\'t acquire any lock either\n        printFirst();  \n        // firstPrinted is atomic because second might be trying to read while this thread is modifying it.\n        firstPrinted = true;\n        // notify waiting threads\n        cv.notify_all();\n    }\n\n    void second(function<void()> printSecond) {\n        // acquire lock, C++17 way\n        unique_lock guard(m);\n        // condition to wait for is => first should have printed.\n        cv.wait(guard, [this] { return this->firstPrinted == true; });\n        // now print\n        printSecond();\n        // secondPrinted need not be atomic, because its access is already protected by mutex in both second and third. \n        secondPrinted = true;\n        // release mutex before notifying\n        guard.unlock();\n        // notify\n        cv.notify_one();\n    }\n\n    void third(function<void()> printThird) {\n        // acquire lock\n        unique_lock guard(m);\n        // condition to wait for is => second should have printed. \n        cv.wait(guard, [this] { return secondPrinted == true; });\n        // now print\n        printThird();\n    }\n    \nprivate:\n    condition_variable cv;\n    mutex m;\n    atomic_bool firstPrinted = false;\n    bool secondPrinted = false;\n};\n```
['C']