4

when a process child is terminated he's sending a SIGCHLD to the parent process. Now, if the parent process have more than one child how the parent process knows which child had sent the signal?

orenma
  • 1,163
  • 2
  • 10
  • 19

2 Answers2

2

The wait() syscall returns the pid of the child that terminated. You can call wait() in your SIGCHLD handler to determine which child terminated.

From the man page:

       wait(): on success, returns the process ID of the terminated child;
   on error, -1 is returned.
shanet
  • 7,246
  • 3
  • 34
  • 46
  • if i use `wait` it will hold until all the child processes end, but i want it to keep running regardless of other child processes. – orenma Nov 06 '13 at 13:39
  • @orenma `wait()` will return when at least one child has terminated, which has happened when your process is sent the `SIGCHLD` signal. Man page: "The wait() system call suspends execution of the calling process until one of its children terminate". However, you can use `waitpid(-1, &status, WNOHANG);` to return immediately if no child is available. Note the `WNOHANG` flag. – shanet Nov 06 '13 at 13:42
  • +1 Indeed, calling `waitpid()` in a loop inside the CHLD signal handler itself — both `wait()` and `waitpid()` are [async-signal-safe](http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_02) — is a longstanding technique. – pilcrow Nov 06 '13 at 13:46
  • @shanet thanks, that was really helpful. but what happens when the signal is sent not when the process termineted but when it been suspended or something like that? – orenma Nov 06 '13 at 13:49
  • Don't quote me on this because I haven't tried it myself, but when a process is suspended it is sent `SIGSTOP` or `SIGTSTP`. The parent process is only notified when the child terminates. I'm wondering if this is not 100% correct though because I know that bash will show me when a child process is suspended. Maybe @pilcrow can jump in here since he/she seems to have a better handle on signals than I do or you'll have to do some research on your own / open another question. – shanet Nov 06 '13 at 14:11
  • @shanet: Whether calls to `wait*()` return for ended children only depends on which options were passed to the call: `UNTRACED` or `WCONTINUED`. – alk Nov 06 '13 at 15:25
2

In addition to the wait() family of calls as in @shanet's answer, the SIGCHLD itself carries that information.

The si_pid member of the siginfo_t member passed to a three-argument signal handler (SA_SIGINFO) contains the child's PID.

Community
  • 1
  • 1
pilcrow
  • 56,591
  • 13
  • 94
  • 135
  • Isn't it possible to the handler to be called once for multiple events? If so, this method wouldn't be reliable. – ikegami Nov 06 '13 at 15:21
  • @ikegami, more precisely put SIGCHLD is not required to queue, so a CHLD generated while one was pending would be lost. However, the SIGCHLD that _does_ trip the handler _will_ carry the PID of the child that generated it. – pilcrow Nov 06 '13 at 17:45