Source code can install a signal handler to catch and handle a certain type of signal in a way that's different than the default.
- Here's a carefully coded example that illustrates how to implement and install a SIGCHLD handler (over two slides). The premise is that dad takes his five kids out to play. Each of the five children plays for a different length of time. When all five children are tired of playing, the six of them (five kids and their dad) all go home.
- Understand that the parent process is modeling dad, and that the child processes are modeling his children. (Code can be found right here).
static const size_t kNumChildren = 5;
static size_t numChildrenDonePlaying = 0;
static void reapChild(int sig) {
exitIf(waitpid(-1, NULL, 0) == -1, kWaitFailed,
stderr, "waitpid failed within reapChild sighandler.\n");
numChildrenDonePlaying++;
sleep(1); // represents time spent doing other useful work
}
int main(int argc, char *argv[]) {
printf("Let my five children play while I take a nap.\n");
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "Failed to install SIGCHLD handler.\n");
for (size_t kid = 1; kid <= 5; kid++) {
pid_t pid = fork();
exitIf(pid == -1, kForkFailed, stderr, "Child #%zu doesn't want to play.\n", kid);
if (pid == 0) {
sleep(3 * kid); // sleep emulates "play" time
printf("Child #%zu tired... returns to dad.\n", kid);
return 0;
}
}