使用 sigaction(2) 忽略 SIGCHLD 信号有什么用?
What is the use of ignoring `SIGCHLD` signal with `sigaction(2)`?
事实证明,我们可以通过将 SIGCHLD
信号指定为被其父级忽略 sigaction()
。但是,似乎 SIGCHLD
默认情况下被忽略了。这怎么行?
int main (void) {
struct sigaction sa;
sa.sa_handler = SIG_IGN; //handle signal by ignoring
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGCHLD, &sa, 0) == -1) {
perror(0);
exit(1);
}
int pid = fork();
if (pid == 0) { //child process
_exit(0);
}
do_something(); //parent process
return 0;
}
SIGCHLD
的默认行为是丢弃信号,但 child 进程一直保持为僵尸,直到 parent 调用 wait()
(或变体) 以获取其终止状态。
但是,如果您明确调用 sigaction()
并设置 SIG_IGN
,这将导致它不会将 child 变成僵尸 - 当 child 退出它时立即收获。参见
获得此行为的 POSIX 方法是调用 sigaction
和 handler = SIG_DFL
以及包含 SA_NOCLDWAIT
的 flags
。这是自 2.6 以来的 Linux。
令人困惑的是,您似乎在假设“SIGCHLD
默认被忽略”意味着信号的默认配置是 SIG_IGN
。
事实并非如此。默认配置为 SIG_DFL
。当您将它设置为 SIG_IGN
时,您实际上是在更改它。在将其设置为 SIG_IGN
后,您可以将其还原为 SIG_DFL
,再次获得原始行为。
事实证明,我们可以通过将 SIGCHLD
信号指定为被其父级忽略 sigaction()
。但是,似乎 SIGCHLD
默认情况下被忽略了。这怎么行?
int main (void) {
struct sigaction sa;
sa.sa_handler = SIG_IGN; //handle signal by ignoring
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGCHLD, &sa, 0) == -1) {
perror(0);
exit(1);
}
int pid = fork();
if (pid == 0) { //child process
_exit(0);
}
do_something(); //parent process
return 0;
}
SIGCHLD
的默认行为是丢弃信号,但 child 进程一直保持为僵尸,直到 parent 调用 wait()
(或变体) 以获取其终止状态。
但是,如果您明确调用 sigaction()
并设置 SIG_IGN
,这将导致它不会将 child 变成僵尸 - 当 child 退出它时立即收获。参见
获得此行为的 POSIX 方法是调用 sigaction
和 handler = SIG_DFL
以及包含 SA_NOCLDWAIT
的 flags
。这是自 2.6 以来的 Linux。
令人困惑的是,您似乎在假设“SIGCHLD
默认被忽略”意味着信号的默认配置是 SIG_IGN
。
事实并非如此。默认配置为 SIG_DFL
。当您将它设置为 SIG_IGN
时,您实际上是在更改它。在将其设置为 SIG_IGN
后,您可以将其还原为 SIG_DFL
,再次获得原始行为。