The concurrency issue is unacceptable.
- We must take steps to programmatically suspend the handling of SIGCHLD siganls until the parent is prepared to handle them.
- Enter the sigset_t type and the collection of functions that can be used to temporarily block the receipt of one or more signal types.
- Here's the working main function (code for entire program can be found right here):
int main(int argc, char *argv[]) {
exitIf(signal(SIGCHLD, reapChild) == SIG_ERR, kSignalFailed,
stderr, "signal function failed.\n");
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
for (size_t i = 0; i < 3; i++) {
sigprocmask(SIG_BLOCK, &mask, NULL);
pid_t pid = fork();
exitIf(pid == -1, kForkFailed,
stderr, "fork function failed.\n");
if (pid == 0) {
sigprocmask(SIG_UNBLOCK, &mask, NULL);
char *listArguments[] = {"date", NULL};
exitIf(execvp(listArguments[0], listArguments) == -1,
kExecFailed, stderr, "execvp function failed.\n");
}
snooze(1);
printf("Job %d added to job list.\n", pid);
sigprocmask(SIG_UNBLOCK, &mask, NULL); // begin handling SIGCHLD signals again
}
return 0;
}
- The sigset_t figure manages the set of signal types to be blocked and unblocked via calls to sigprocmask.
- Note the call to sigprocmask(SIG_BLOCK, &mask, NULL);, which informs the kernel that the calling process isn't interested in handling any SIGCHLD events until after the spawned child process is added to the job list. Note, also, the call to sigprocmask(SIG_UNBLOCK, &mask, NULL); appears after the child process pid has been added to the job list (gestured via printf).
- As it turns out, the forked process inherits the blocked signals vector, so it too needs to lift the block via its own call to sigprocmask(SIG_UNBLOCK, &mask, NULL);. In this example, it doesn't matter, but it would matter if the forked child process itself forked off child processes of its own.
myth22> ./job-list-synchronization
Wed Oct 11 9:49:23 PDT 2017
Job 29619 added to job list.
Job 29619 removed from job list.
Wed Oct 11 9:49:24 PDT 2017
Job 29620 added to job list.
Job 29620 removed from job list.
Wed Oct 11 9:49:25 PDT 2017
Job 29621 added to job list.
Job 29621 removed from job list.
myth22>