我有一个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?
答案 0 :(得分:2)
子进程确实派生了两个守护进程……在这种情况下,
read()
不返回的原因可能是什么?
当子进程终止时,分叉的进程仍具有打开的文件描述符。因此,read
调用永远不会返回0。
这些守护进程应关闭所有文件描述符并打开文件进行记录。
答案 1 :(得分:0)
read(2)
在有死亡孩子的管道上阻塞的可能原因(最常见)是,父管道尚未关闭管道的写入侧,因此仍然有一个开放的(用于写入)描述符那个管子在从父进程中读取管道之前,请先关闭管道的写入侧。这个孩子已经死了(你说是僵尸),所以这不可能是打开管道书写侧的过程。并且不要忘了wait(2)
为父母中的孩子,否则您将得到一个充满僵尸:)
请记住,您必须在代码中进行两次关闭:
父进程中的一个关闭管道的写操作,而父进程仅具有读取描述符。
子进程中的一个(在exec(2)
之前)关闭了管道的读取端,而子进程仅带有写入描述符。
如果您想使用pipe(2)
向孩子发送信息,请在上述两点上更改写作的阅读量,反之亦然。