read()挂在僵尸进程上

时间:2018-11-30 10:51:23

标签: c linux pipe fork zombie-process

我有一个while循环,通过将子进程的stdout重定向到父进程,使用阻塞I / O从子进程读取数据。通常,子进程退出后,由于从中读取的管道被子进程关闭,因此在这种情况下,将返回阻塞read()

现在,我遇到了这样的情况:对于以僵尸状态结尾的子进程,read()调用不会退出。因此,操作系统正在等待我的代码获取它,但是相反,我的代码在read()调用中处于阻塞状态。

在挂起时,子进程本身没有任何子进程正在运行,并且在/proc/<child process PID>/fd中查看时,我看不到列出的任何文件描述符。但是,子进程确实派生了两个守护进程,它们的目的似乎是监视子进程(子进程是我无法控制的专有应用程序,因此很难确定)。

从终端运行时,我尝试从read()退出的子进程会自动退出,然后守护进程也将其分叉的进程也终止。

Linux版本是4.19.2。

在这种情况下,read()不返回的原因可能是什么?

跟进:How to avoid `read()` hanging in the following situation?

2 个答案:

答案 0 :(得分:2)

  

子进程确实派生了两个守护进程……在这种情况下,read()不返回的原因可能是什么?

当子进程终止时,分叉的进程仍具有打开的文件描述符。因此,read调用永远不会返回0。

这些守护进程应关闭所有文件描述符并打开文件进行记录。

答案 1 :(得分:0)

read(2)在有死亡孩子的管道上阻塞的可能原因(最常见)是,父管道尚未关闭管道的写入侧,因此仍然有一个开放的(用于写入)描述符那个管子在从父进程中读取管道之前,请先关闭管道的写入侧。这个孩子已经死了(你说是僵尸),所以这不可能是打开管道书写侧的过程。并且不要忘了wait(2)为父母中的孩子,否则您将得到一个充满僵尸:)

的系统

请记住,您必须在代码中进行两次关闭:

  • 父进程中的一个关闭管道的写操作,而父进程仅具有读取描述符。

  • 子进程中的一个(在exec(2)之前)关闭了管道的读取端,而子进程仅带有写入描述符。

如果您想使用pipe(2)向孩子发送信息,请在上述两点上更改写作的阅读量,反之亦然。