Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C read()挂起僵尸进程_C_Linux_Pipe_Fork_Zombie Process - Fatal编程技术网

C read()挂起僵尸进程

C read()挂起僵尸进程,c,linux,pipe,fork,zombie-process,C,Linux,Pipe,Fork,Zombie Process,我有一个while循环,通过将子进程的stdout重定向到父进程,使用阻塞I/O从子进程读取数据。通常,只要子进程退出,在这种情况下就会返回阻塞read(),因为从中读取的管道被子进程关闭 现在我遇到了一个情况,即对于完成的子进程,read()调用不会退出。子进程最终处于僵尸状态,因为操作系统正在等待我的代码获取它,但是我的代码在read()调用中被阻塞 在挂起时,子进程本身没有任何子进程在运行,在查看/proc//fd时,我没有看到列出任何文件描述符。然而,子进程确实分叉了两个守护进程,它们的

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

现在我遇到了一个情况,即对于完成的子进程,
read()
调用不会退出。子进程最终处于僵尸状态,因为操作系统正在等待我的代码获取它,但是我的代码在
read()
调用中被阻塞

在挂起时,子进程本身没有任何子进程在运行,在查看
/proc//fd
时,我没有看到列出任何文件描述符。然而,子进程确实分叉了两个守护进程,它们的目的似乎是监视子进程(子进程是我无法控制的专有应用程序,因此很难说清楚)

当从终端运行时,我尝试从中读取的子进程将自动退出,反过来,守护进程也会终止

Linux版本是4.19.2

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

后续行动:

但是,子进程没有分叉两个守护进程。。。在这种情况下,
read()
不返回的原因可能是什么

分支进程在子进程终止时仍然打开文件描述符。因此,
read
call永远不会返回0

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

在具有死子级的管道上阻塞
read(2)
的一个可能原因(最常见)是父进程尚未关闭管道的写入端,因此该管道仍然有一个打开的(用于写入)描述符。从父进程中读取之前,请关闭管道的写入端。孩子死了(你说的是僵尸),所以它不可能是管道书写端打开的过程。别忘了等待(2)父系统中的子系统,否则你会看到一个充满僵尸的系统
:)

请记住,您必须在代码中完成两个关闭:

  • 在父进程中,关闭管道的写入端,使父进程只剩下一个读取描述符

  • 子进程中的一个(就在
    exec(2)
    ing之前)关闭管道的读取端,子进程只剩下一个写入描述符


如果您想使用
管道(2)
向子进程发送信息,请在上述两点中更改写入的读数,反之亦然。

为什么不在子进程被终止时使用信号处理程序关闭管道?@bumsikim这里没有进程被终止,子进程应该直接退出。我将对问题进行编辑以澄清这一点。为
SIGCHLD
设置一个信号处理程序,并通过调用
wait()
waitpid()
@alk获取其中的子项,感谢指针,我将研究它。尽管如此,我还是不明白为什么
read()
不会在子进程退出后简单地返回。正如你提到的,它仍然处于僵尸状态。啊,当然……不幸的是,我没有控制守护进程,所以我必须走
SIGCHLD
路线。@TonvandenHeuvel如果你控制调用
fork
的代码,那么那就是关闭文件描述符的地方-就在
fork
之后。是的,我知道,但在这种情况下,我不想关闭子进程之外的标准,我想从中读取。@TonvandenHeuvel您的子进程分叉,现在您有两个进程。您只需要关闭子对象的子对象中的文件描述符。“他们在孩子身上保持开放,”马克西梅戈拉什金澄清道;我无法控制子进程及其派生的守护进程。我只能控制父应用程序。感谢您的建议,这些操作是在父进程中执行的。读取端在子进程中没有关闭,因为在文件描述符上设置了
O_CLOEXEC
,这是不需要的。父进程阻塞的原因是子进程分叉的守护进程仍然有文件描述符打开到管道,用于将STDOUT从子进程重定向到父进程。另请参阅此问题中的后续问题链接。好吧,这可能是另一种可能性,我不记得读过您在构建过程的深层层次结构时。。。。事实上,我只知道一个父母和一个僵尸孩子。僵尸在系统上什么也做不了。这是一个死过程。它从未执行过,也没有附加任何资源,比如文件描述符或任何其他东西。问题就在这里:“子进程确实分叉了两个守护进程,它们的目的似乎是监视子进程(子进程是我无法控制的专有应用程序,因此很难说清楚)。”