Handling multiple SIGCHLD
On Linux, multiple children terminating before you read a SIGCHLD
with signalfd()
will be compressed into a single SIGCHLD
. This means that when you read the SIGCHLD
signal, you have to clean up after all children that have terminated:
// Do this after you've read() a SIGCHLD from the signalfd file descriptor:
while (1) {
int status;
pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0) {
break;
}
// something happened with child 'pid', do something about it...
// Details are in 'status', see waitpid() manpage
}
I should note that I have in fact seen this signal compression when two child processed terminated at the same time. If I did only a single waitpid()
, one of the children that terminated was not handled; and the above loop fixed it.
Corresponding documentation:
- http://man7.org/linux/man-pages/man7/signal.7.html "By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued"
- http://man7.org/linux/man-pages/man3/sigwait.3p.html "If prior to the call to sigwait() there are multiple pending instances of a single signal number, it is implementation-defined whether upon successful return there are any remaining pending signals for that signal number."
Handling multiple SIGCHLD
On Linux, multiple children terminating before you read a SIGCHLD
with signalfd()
will be compressed into a single SIGCHLD
. This means that when you read the SIGCHLD
signal, you have to clean up after all children that have terminated:
// Do this after you've read() a SIGCHLD from the signalfd file descriptor:
while (1) {
int status;
pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0) {
break;
}
// something happened with child 'pid', do something about it...
// Details are in 'status', see waitpid() manpage
}
I should note that I have in fact seen this signal compression when two child processed terminated at the same time. If I did only a single waitpid()
, one of the children that terminated was not handled; and the above loop fixed it.
Corresponding documentation:
- http://man7.org/linux/man-pages/man7/signal.7.html "By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued"
- http://man7.org/linux/man-pages/man3/sigwait.3p.html "If prior to the call to sigwait() there are multiple pending instances of a single signal number, it is implementation-defined whether upon successful return there are any remaining pending signals for that signal number."
how to handle multiple signals by order of arrival in C
As long as you use sigaction
and not the problematic signal
function to setup your signal handler, you can be sure (unless you specify otherwise) that your signal handler will not be interrupted by another occurrence of the signal it's handling. However it's possible if many child processes all die at once that you might not receive a signal for each. On each SIGCHLD
, the normal procedure is to attempt to wait
for children until your wait
-family function says there are no children left to wait for. At this point, you can be sure that any further child termination will give you a new SIGCHLD
.
Also, since you're very restricted as to what functions you can use from a signal handler, you'd probably be better off just setting some sort of flag or otherwise notifying your main program loop that it should check for terminated children via one of the wait
interfaces.
And finally, yes, a SIGCHLD
is delivered regardless of the reason the child terminated - including if it was killed by the parent.
Related Topics
How to Send a File as an Email Attachment Using Linux Command Line
How to Compare Two Strings in Dot Separated Version Format in Bash
Get Destination Address of a Received Udp Packet
What Is the Runtime Performance Cost of a Docker Container
Glibc Scanf Segmentation Faults When Called from a Function That Doesn't Align Rsp
Sed In-Place Flag That Works Both on MAC (Bsd) and Linux
How to Prevent a Background Process from Being Stopped After Closing Ssh Client in Linux
What Does Set -E Mean in a Bash Script
How to Pass Command Output as Multiple Arguments to Another Command
How to Change Permissions For a Folder and Its Subfolders/Files
How Does "Cat ≪≪ Eof" Work in Bash
Get Exit Code of a Background Process
Linux Blocking Vs. Non Blocking Serial Read
How to Generate a Core Dump in Linux on a Segmentation Fault
Using the Passwd Command from Within a Shell Script
How to Compile a 32-Bit Binary on a 64-Bit Linux Machine With Gcc/Cmake