我有这个c代码
/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
/* Wait for all dead processes.
* We use a non-blocking call to be sure this signal handler will not
* block if a child was cleaned up in another part of the program. */
//printf("Inside handler: \n");
while (waitpid(-1, NULL, WNOHANG) > 0) {
printf("reaped\n");
}
//printf("Outside handler: \n");
}
int main (int argc, char *argv[])
{
struct sigaction act;
int i;
memset (&act, 0, sizeof(act));
act.sa_handler = sigchld_hdl;
if (sigaction(SIGCHLD, &act, 0)) {
perror ("sigaction");
return 1;
}
/* Make some children. */
for (i = 0; i < 5; i++) {
switch (fork()) {
case -1:
perror ("fork");
return 1;
case 0:
exit(0);
return 0;
default:
//printf("inside parent\n");
printf("Created child %d\n", i);
}
}
/* Wait until we get a sleep() call that is not interrupted by a signal. */
while (sleep(1)) {
printf("inside parent while loop\n");
}
return 0;
}
我调用了 5 次 fork,所以我预计总共有 5 个子进程和 1 个父进程。当我运行这段代码时,我得到了这个输出
Created child 0
Created child 1
reaped
reaped
Created child 2
Created child 3
Created child 3
reaped
reaped
Created child 4
reaped
inside parent while loop
我不太明白为什么我会看到 child3 两次。关于 i 不应该有任何重复,因为 i 在每次迭代中递增。
有人能解释一下为什么我会看到 child3 两次吗?
最佳答案
stdio 缓冲区的状态包含在进程的内存空间中。如果在 fork 时缓冲区不为空,则父进程和子进程都有一份信息副本,内容为 "Child process 3\n"
is in the stdout buffer, waiting to be flushed .
他们最终都会把它冲掉。
您可以通过在子进程中调用 _exit
而不是 exit
来避免这种情况。 exit
通常是一个坏主意,当您处于一个自创建以来尚未成功完成 exec 的进程中时。
关于c - fork 为这个 c 程序生成不正确的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43600347/