Waking up thread from signal handler
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. Ie 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:
notify_one()
in a signal handler (corrct me if I'm wrong) 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.
Assuming that your vendor's standard library uses the pthread_cond_*
functions to implement C++11 condition variables (libstdc++ and libc++ do this), the pthread_cond_*
functions are not async-signal-safe so cannot be invoked from a signal handler.
From http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_broadcast.html:
It is not safe to use the pthread_cond_signal() function in a signal handler that is invoked asynchronously. Even if it were safe, there would still be a race between the test of the Boolean pthread_cond_wait() that could not be efficiently eliminated.
Mutexes and condition variables are thus not suitable for releasing a waiting thread by signaling from code running in a signal handler.
If you're comfortable using semaphores, sem_post
is designated async-signal-safe. Otherwise, your options for signal handling are the usual ones: the classic self-pipe, a signal handling thread blocked on sigwait
/ sigwaitinfo
, or platform-specific facilities (Linux signalfd
, etc.).
上一篇: 如何将可变参数传递给std ::线程?
下一篇: 从信号处理程序唤醒线程