Are there alternative ways to catch potentially missed signals with
condition variables?
Consider the following simplified example:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mutex;
std::condition_variable cv;
bool cv_flag = false; // I'm talking about this flag here
void startThread1()
{
std::cout << "thread 1 prints first\n";
{
// Set the flag (lock to be safe)
std::unique_lock<std::mutex> lock(mutex);
cv_flag = true;
}
cv.notify_one();
}
void startThread2()
{
std::unique_lock<std::mutex> lock(mutex);
if (!cv_flag)
{
cv.wait(lock);
}
std::cout << "thread 2 prints second\n";
}
int main()
{
std::thread thread1(startThread1);
std::thread thread2(startThread2);
thread1.join();
thread2.join();
}
Here, cv_flag is used to make sure that thread 2 does not lock and wait()
if thread 1 has already sent the signal with notify_one(). Without it,
thread 2 might lock and wait() after thread 1 has already called
notify_one(), resulting in an indefinite hang since thread 2 is waiting
for something that's already happened.
I've seen lots of code like this where something like cv_flag is used
solely to detect potentially missed signals.
Is this really the only way to do this? And the cleanest and simplest? I
think it would be great if something like:
std::mutex mutex;
std::condition_variable cv;
// no more need for cv_flag
void startThread1()
{
std::cout << "thread 1 prints first\n";
cv.notify_one();
}
void startThread2()
{
std::unique_lock<std::mutex> lock(mutex);
cv.wait_unless_already_signaled(lock); // Unfortunately, this function
doesn't exist
std::cout << "thread 2 prints second\n";
}
Is there anything like wait_unless_already_signaled()? If not, is there a
technical reason for it not existing?
No comments:
Post a Comment