Reputation: 3726
I am studying this example. I have found this question and thought that I will get an answer, but I still have a question.
I post the the code here for convenience:
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::cout << "------------------------\n";
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();
return 0;
}
Should not the statement std::unique_lock<std::mutex> lk(m);
block the main thread because mutex m
is locked by worker_thread
? If yes, isn't the statement cv.wait(lk, []{return processed;});
after it unnecessary in this example? When main thread can lock the mutex, processed
will be already true.
Upvotes: 1
Views: 1786
Reputation: 18964
The call to wait
unlocks the mutex for the duration of the wait. See http://en.cppreference.com/w/cpp/thread/condition_variable/wait.
EDIT: Which is explicitly stated in the answer to the question you linked to: https://stackoverflow.com/a/32030975/212870
EDIT 2: It is not true that "When main thread can lock the mutex, processed
will already be true". The worker thread may not even have started yet, or if it has it may not have seen that ready
is set.
Upvotes: 1
Reputation: 506
Line cv.wait(lk, []{return ready;});
does the following if ready
is false
:
Unlocks the mutex lk
Blocks the thread waiting for notification
When notification arrives, unblocks the thread and locks the mutex lk
So the main thread does not block on std::lock_guard<std::mutex> lk(m);
as the mutex is unlocked by worker thread.
Upvotes: 0