I'm reading this std::condition_variable
example:
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});
// after the wait, we own the lock.
std::cout << "Worker thread is processing data\n";
data += " after processing";
// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completed\n";
// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}
int main()
{
std::thread worker(worker_thread);
data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return processed;});
}
std::cout << "Back in main(), data = " << data << '\n';
worker.join();
}
Let's focus on the beggining:
std::thread worker(worker_thread);
here, we start the worked, which will lock the mutex immediately:
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});
Then, we lock the mutex on main to change the value of ready
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
but how is it possible that we even arrive at the line ready=true
? The mutext m
is blocked from the worked thread, so the line std::lock_guard<std::mutex> lk(m);
will wait until the mutex m
is unlocked. As I understand, when a mutex is locked and we try to lock it, we'll wait until it gets unlocked. However, it'll never get unlocked because the worked thread is waiting, therefore not releasing it.
std::condition_variable
releases its lock while it's waiting. – Miles Budnekstd::lock_gaurd
is destroyed when it gets out of scoop that is -}
then its unlock this is part of the RAII paradigm read the doc – yaodavwait
: "Atomically unlockslock
, blocks the current executing thread, and adds it to the list of threads waiting on*this
. " (Emphasis mine.) – molbdnilo