我已经看过一些关于此的话题,但无法解决 -
我正在分叉两次,但是当等待最后一次触发时它会卡在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,但在第二个上它只是阻止。
但我在屏幕上看到第二个过程已完成(来自过程输出)。
欢迎任何有关该主题的帮助。
谢谢。答案 0 :(得分:2)
如果某个流程没有未收集的子项(wait()
将返回wait()
并将-1
设置为errno
,则流程调用ECHILD
会出错那个案例),wait()
挂起的事实表明 是一个尚未收集的子进程。一旦该子进程实际上已终止 - 包括它是否已在wait()
调用之前终止 - 父进程就有资格进行调度,并应立即从wait()
返回。因此wait()
调用挂起是一个非常好的迹象,表明两个子进程中的一个实际上还没有退出。
正如我在评论中写的那样,孩子的输出并不一定是它已经退出的可靠指示。孩子退出时会变成僵尸,直到它被收集,你可以在流程表中检查它。
您的文件描述符处理看起来有点奇怪,这可能是您问题的根源。首先,如果您要将管道FD复制到子项的标准流中,则应使用dup2()
以明确指定,而不是close()
+ {{1} }。然而,更可能是您的实际问题是父进程未能关闭管道FD的副本。如果第二个孩子正在等待其标准输入(来自管道)的EOF,那么父母未能关闭该管道的书写结束副本将阻止孩子终止。