Working with asynchronous signals in a multithreaded program

A book on the Linux programming interface mentioned a method for working with asynchronous signals in a multi-threaded program:

  • All threads block all asynchronous signals that the process can receive. The easiest way to do this is to block signals in the main thread before any other thread is created. Each subsequently created thread inherits a copy of the main thread.
  • create a separate dedicated stream that accepts incoming signals using sigwaitinfo() , sigtimedwait() or sigwait() .

The advantage of this approach is that asynchronously generated signals are received synchronously. Since it accepts incoming signals, a dedicated thread can safely change common variables (under mutex control) and call non-asynchronous functions. It can also vary the signal conditions and use a different connection of flows and processes and synchronization mechanisms.

Now questions:

  • When the kernel wants to deliver signals, it selects one of the threads within the process arbitrarily. how can he know to transmit a signal to a dedicated stream?
  • The pthread APIs are nonsynchronous functions. so how can we use them inside a signal handler?
+12
c multithreading pthreads signals
Jun 03 2018-11-11T00:
source share
3 answers

When the core delivers a process-oriented signal, it selects one of the threads that does not block the signal. This means that it never selects any of the threads except the signal processing thread (which acts as if it is unlocked when it is locked in sigwaitinfo() or similar). In other words: the kernel knows where to give the signal, because you have packed such things that the signal processing stream is the only stream that has ever been allowed to deliver the signal.

In the signal handler, you are not using the pthreads API or any non-synchronous signaling functions. The above solution does not process signals in signal handlers - it processes signals in the normal flow of the signal processing stream after sigwaitinfo() returns. This allows it to access non-asynchronous signal functions, which is the whole.

+8
Jun 03 2018-11-11T00:
source share

Remember, the suggestion is to block the signal (using pthread_sigmask ()) at an early stage in the process before you create any threads or receive any signals.

To answer your questions:

  • Read the sigwait () (and / or sigwaitinfo () ) man page. When the kernel wants to send your process a signal, but the whole thread blocks the signal, the signal becomes "queued". It remains in the queue until either (a) the thread releases the signal; or (b) some streaming calls to sigwait () or sigwaitinfo () in the signal. The suggestion is to allocate a thread for the latter.

  • The idea is that you never run any signal handlers because the thread never blocks the signal. Instead, a single thread expects a signal using sigwait (), and then processes the signal. All this happens outside the context of signal processing, which is the beauty of the proposal.

+3
Jun 03 2018-11-11T00:
source share

You can indirectly call pthread APIs from a signal handler using a different mechanism. In the main thread, create a Unix domain socket that listens for specific commands. The signal handler may have code to connect to the socket and send commands to the main thread to call the pthread API you want to call.

0
Aug 12 '14 at 5:58
source share



All Articles