I understand that about the only thing, a signal handler in ISO/C++11 is allowed to do is to read from or write to a lock free atomic variable or a volatile sig_atomic_t
(I believe, POSIX is a little bit more permissive and allows to call a bunch of system functions).
I was wondering, if there is any way, to wake up a thread that is waiting on a condition variable. I.e. something like:
#include <mutex>
#include <atomic>
#include <condition_variable>
std::mutex mux;
std::condition_variable cv;
std::atomic_bool doWait{ true };
void signalHandler(int){
doWait = false;
cv.notify_one();
}
int main() {
//register signal handler
//Do some stuff
{//wait until signal arrived
std::unique_lock<std::mutex> ul(mux);
cv.wait(ul, []{return !doWait; });
}
//Do some more stuff
}
Which has at least two problems:
- I believe, I'm not allowed to call
notify_one()
in a signal handler (corrct me if I'm wrong) - The signal could arrive just between the check for
doWait
and when the thread goes to sleep, so it would never wake up (obviously, I can't lock the mutex in the signalHander to avoid that).
So far, the only solution I can see is to implement busy waiting on the doWait
variable (probably sleep for a couple of milliseconds in each iteration), which strikes me as quite inefficient.
Note that even though, my program above has only one thread, I labeled my question with multithreading, because it is about thread control primitives. If there is no solution in standard c++ I'd be willing to accept a solution using Linux/POSIX specific functions.