I found the following example for condition variable on www.cppreference.com, http://en.cppreference.com/w/cpp/thread/condition_variable. The call to cv.notify_one() is placed outside the lock. My question is if the call should be made while holding the lock to guarantee that waiting threads are in fact in waiting state and will receive the notify signal.
#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();
}
Should the notify_one() call be moved inside the lock to guarantee waiting threads receive the notify signal,
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
cv.notify_one();
std::cout << "main() signals data ready for processing\n";
}
ready
,data
orprocessed
are not part of the question. – Patricio