I have a parent process spanning several child processes. I want to know when any child process exits by registering a SIGCHLD
signal handler.
The question is, what happens if another SIGCHLD
(or any other signal) is received, while the parent process is already in a signal handler?
I can think of the following outcomes:
- The signal is ignored
- The signal is queued, and will be processed as soon as the current handler returns
- The current handler is in turn interrupted, just like the main program
Which one is correct?
In your concrete example (the same signal being received), the signal is delivered after the signal handler has finished (so bullet point #2 is correct). Note, however, that you may "lose" signals.
The reason for that is that while a signal is being inside its handler, it is blocked. Blocked signals are set to pending, but not queued. The term "pending" means that the operating system remembers that there is a signal waiting to be delivered at the next opportunity, and "not queued" means that it does this by setting a flag somewhere, but not by keeping an exact record of how many signals have arrived.
Thus, you may receive 2 or 3 (or 10) more SIGCHLD
while in your handler, but only see one (so in some cases, bullet point #1 can be correct, too).
Note that several flags that you can pass to sigaction
can affect the default behaviour, such as SA_NODEFER
(prevents blocking signal) and SA_NOCLDWAIT
(may not generate signal at all on some systems).
Now of course, if you receive a different type of signal, there's no guarantee that it won't interrupt your handler. For that reason, one preferrably doesn't use non signal safe functions.