17

I have a parent process spawning 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?

BenMorel
  • 34,448
  • 50
  • 182
  • 322

1 Answers1

9

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.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • So if I summarize, while in the signal handler for `SIGCHLD`, other `SIGCHLD` signals will be either lost, or delivered *after* the handler has returned. But any other kind of signal will *interrupt* the signal handler itself? – BenMorel Aug 26 '13 at 11:08
  • Yes for 1 and 2 (at most 1 extra signal is delivered _after_ the handler returns). For 3, it's also "yes", albeit with a "but". Synchronous signals (say, `SIGSEGV`) will _literally_ interrupt the handler, but asynchronous signals of course still follow the normal rules, i.e. they're delivered at unknown but well-defined times, e.g. at kernel/user switches, so they will _not literally_ interrupt the handler. But, they may very well be delivered while the handler runs if you give them an opportunity (so use [async-signal-safe](http://man7.org/linux/man-pages/man7/signal.7.html) functions only). – Damon Aug 26 '13 at 11:15