waitpid and signal handler, C

c ipc waitpid sigaction

327 观看

1回复

6 作者的声誉

I tried to find an answer to my question at this post: Signal handler and waitpid coexisting but for me isn't very clear at the moment.

I try to explain my problems:

I'm trying to write a C program that concerns IPC between a parent process and its children. The parent process creates N child processes, then it waits for the termination in a loop like this:

while((pid_term = waitpid(-1, &status, 0)) != -1)

After X seconds, parent receives SIGALRM, then with the sigaction system call, it catches the alarm:

struct sigaction act;
act.sa_handler = alarmHandler;
sigemptyset(&act.sa_mask);

act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);  

But, when the handler function returns, the waitpid also returns -1, and the parent process exits from the while loop above. At the moment, the handler function has an empty body.

I ask myself what happened — why did waitpid() return -1 after the handler invocation even though most of the children are still alive? Why doesn't this happen with signal() function?

作者: gaet 的来源 发布者: 2017 年 12 月 27 日

回应 1


3

104891 作者的声誉

The default behavior of signal handlers established by sigaction is to interrupt blocking system calls; if you check errno after the alarm fires you should observe it to be set to EINTR. This behavior is almost never what you want; it's only the default for backward compatibility's sake. You can make it not do this by setting the SA_RESTART bit in sa_flags:

struct sigaction act;
act.sa_flags = SA_RESTART;
act.sa_handler = alarmHandler;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM, &act, 0);

One of the most important reasons to use sigaction instead of signal, is that when you use signal it is unpredictable whether or not the signal handler will interrupt blocking system calls. (The System V lineage picked one semantic and the BSD lineage picked the other.)

作者: zwol 发布者: 2017 年 12 月 27 日
32x32