【发布时间】:2022-11-25 05:16:56
【问题描述】:
在 CSAPP 书籍第 8 章的这个例子中:
\#include "csapp.h"
/* WARNING: This code is buggy! \*/
void handler1(int sig)
{
int olderrno = errno;
if ((waitpid(-1, NULL, 0)) < 0)
sio_error("waitpid error");
Sio_puts("Handler reaped child\n");
Sleep(1);
errno = olderrno;
}
int main()
{
int i, n;
char buf[MAXBUF];
if (signal(SIGCHLD, handler1) == SIG_ERR)
unix_error("signal error");
/* Parent creates children */
for (i = 0; i < 3; i++) {
if (Fork() == 0) {
printf("Hello from child %d\n", (int)getpid());
exit(0);
}
}
/* Parent waits for terminal input and then processes it */
if ((n = read(STDIN_FILENO, buf, sizeof(buf))) < 0)
unix_error("read");
printf("Parent processing input\n");
while (1)
;
exit(0);
}
它生成以下输出:
......
Hello from child 14073
Hello from child 14074
Hello from child 14075
Handler reaped child
Handler reaped child //more than one child reaped
......
用于waitpid() 的 if 块用于生成waitpid() 无法收割所有孩子的错误。虽然我知道 waitpid() 将被放入 while() 循环中以确保收割所有孩子,但我不明白的是 为什么只有一个waitpid()调用,却能够收获多个孩子(注意输出中有多个孩子被处理程序收获)?根据这个回答:Why does waitpid in a signal handler need to loop?
waitpid()只能收割一个孩子。
谢谢!
更新:这无关紧要,但处理程序已按以下方式更正(也取自 CSAPP 书):
void handler2(int sig)
{
int olderrno = errno;
while (waitpid(-1, NULL, 0) > 0) {
Sio_puts("Handler reaped child\n");
}
if (errno != ECHILD)
Sio_error("waitpid error");
Sleep(1);
errno = olderrno;
}
在我的 Linux 计算机上运行这段代码。
【问题讨论】:
标签: c operating-system computer-science cpu-architecture signal-handling