Dealing With Asynchronous Signals In Multi Threaded Program Dealing With Asynchronous Signals In Multi Threaded Program multithreading multithreading

Dealing With Asynchronous Signals In Multi Threaded Program


When the kernel delivers a process-directed signal, it chooses one of the threads that does not have the signal blocked. This means that it never chooses any of the threads apart from the signal-handling thread (which acts like it has the signal unblocked while it is blocked in sigwaitinfo() or similar). In other words: the kernel knows where to deliver the signal, because you have arranged things such that the signal-handling thread is the only thread that is ever allowed to deliver the signal to.

You do not use the pthreads API, or any non-async-signal-safe functions in a signal handler. The solution outlined does not handle the signals within signal handlers - it handles the signals within the normal execution flow of the signal-handling thread, after sigwaitinfo() returns. This allows it to access non-async-signal-safe functions, which is the whole point.


Remember that the proposal is to block the signal (using pthread_sigmask()) early in the process's execution, before your spawn any threads or receive any signals.

To answer your questions:

  1. Read the man page for sigwait() (and/or sigwaitinfo()). When the kernel wants to send your process a signal but all of the thread have the signal blocked, the signal gets "queued". It remains queued until either (a) some thread unblocks the signal; or (b) some thread calls sigwait() or sigwaitinfo() on the signal. The proposal here is to dedicate a thread to do the latter.

  2. The idea is that you never run any signal handlers, because no thread ever unblocks the signal. Instead, one thread waits for the signal with sigwait(), and then it processes the signal. This all happens outside of signal-handling context, which is the beauty of the proposal.


You can indirectly call pthread APIs from a signal handler using another mechanism. In the main thread, create a Unix domain socket that listens to certain commands. The signal handler can have code to connect to the socket and send commands to the main thread to call the pthread API you desire to be called.