确实linux永远不会结束子进程,直到父节点结束?
问题描述:
请在C考虑下面的代码:确实linux永远不会结束子进程,直到父节点结束?
int main()
{
pid_t cpid;
cpid = fork();
if (cpid == -1)
{
perror("fork");
return 0;
}
if (cpid == 0)
{
printf("I'm child\n");
_exit(0);
}
else
{
while(1)
{
printf("I'm parent\n");
sleep(1);
}
}
return 0;
}
运行代码后,我希望它运行的孩子,离开它一旦完成。 但是当我运行
pgrep executable_name
或
ps fax
它显示的子进程ID,如果它只是工作过程的历史垃圾或它确实没有结束/终止我不知道孩子的过程?
在此先感谢
答
孩子将一直等到父母死亡或父母用wait
系统调用清除它。 (在孩子终止和清理之间的时间内,它被称为僵尸进程。)
原因是父级可能对子级的返回值或最终输出感兴趣,所以进程入口保持激活状态直到查询信息。
编辑:
使用SIGCHLD处理程序,立即清理,当他们死的过程不会阻塞示例代码:
要留意的是,系统调用(如睡眠,选择,或文件读/写)可以被信号中断。这是你在unix中应该处理的正常事情 - 它们失败并将errno设置为EINTR。发生这种情况时,您可以再次尝试完成操作。这就是为什么我的示例代码在父代中调用了两次睡眠 - 第一次长睡会被孩子死亡打断,然后第二次较短的睡眠让我们确认在父母死亡之前实际清理了进程。
顺便说一句,信号处理程序通常不应该做太多,他们应该尽快返回,并避免不是线程安全的东西;通常不鼓励在其中印刷。我在这里做过,所以你可以看到发生的一切。
为了清楚起见:* only *当进程处于“僵尸”状态时进程表条目存活;所有其他资源都被释放。 – zwol
好吧,这是一个解决方案,并感谢您给出的原因,但不等待父母,直到孩子的状态改变?我想要叉的并行化在第一个地方 – madz
是的,等待块。你也可以设置一个SIGCHLD处理程序,并且只有等到它被触发时才能确保它不会被阻塞。信号在小孩终止时发送。您也可以忽略它,孩子在父母结束时会自动清理。 –