在fork()之后等待wait()

时间:2015-05-26 15:38:46

标签: c fork wait

我已经看过一些关于此的话题,但无法解决 -

我正在分叉两次,但是当等待最后一次触发时它会卡在wait()上,如果我移除了wait()它继续前进,但显然它不会等待:

这是相关代码:

library(repmis)
library(evmix)
data=source_data("https://www.dropbox.com/s/r7i0ctl1czy481d/test.csv?dl=0")[,1]
test=fdwm(data,c(0.9150062,75.4699181,quantile(data,0.98),11.21,87.41,0.05))

我添加了一些测试以查看一些PID输出和内部发生的事情,它等待第一个chil过程完成,并打印正确的ID,但在第二个上它只是阻止。

但我在屏幕上看到第二个过程已完成(来自过程输出)。

欢迎任何有关该主题的帮助。

谢谢。

1 个答案:

答案 0 :(得分:2)

如果某个流程没有未收集的子项(wait()将返回wait()并将-1设置为errno,则流程调用ECHILD会出错那个案例),wait()挂起的事实表明 是一个尚未收集的子进程。一旦该子进程实际上已终止 - 包括它是否已在wait()调用之前终止 - 父进程就有资格进行调度,并应立即从wait()返回。因此wait()调用挂起是一个非常好的迹象,表明两个子进程中的一个实际上还没有退出。

正如我在评论中写的那样,孩子的输出并不一定是它已经退出的可靠指示。孩子退出时会变成僵尸,直到它被收集,你可以在流程表中检查它。

您的文件描述符处理看起来有点奇怪,这可能是您问题的根源。首先,如果您要将管道FD复制到子项的标准流中,则应使用dup2()以明确指定,而不是close() + {{1} }。然而,更可能是您的实际问题是父进程未能关闭管道FD的副本。如果第二个孩子正在等待其标准输入(来自管道)的EOF,那么父母未能关闭该管道的书写结束副本将阻止孩子终止。