为什么 parent 进程必须在调用 wait( ) 之前关闭管道的所有文件描述符?

Why parent process has to close all file descriptors of a pipe before calling wait( )?

我不知道为什么 parent 进程在调用 wait() 之前需要关闭管道的两个文件描述符?

我有一个 C 程序:

  1. Parent 创建 child_a,它使用 execvp 执行 ls -l,并写入管道(在关闭管道的读取端之后)。
  2. Parent 创建另一个 child(不关闭管道的任何文件描述符),称为 child_b,它通过从管道读取来执行 'wc'。(关闭写入后管道末端)。
  3. Parent 通过调用 wait() 两次等待两个 children 完成。

我注意到如果 parent 在调用 wait() 系统调用之前没有关闭管道的两个文件描述符,程序将被阻塞。此外,在阅读了在线发布的几个问题后,看起来这是一般规则,需要完成。但是我找不到必须这样做的原因?

如果 parent 没有关闭管道的文件描述符,为什么 wait() 而不是 return?

我在想,在最坏的情况下,如果parent不关闭管道的文件描述符,那么唯一的后果就是管道将继续存在(这是一种资源浪费).但是没想到这会阻塞child进程的执行(可以看出是因为wait()没有return)。

还要记住,parent 根本没有使用管道。它是child_a写入管道,child_b从管道读取。

如果父进程不关闭管道的写入端,则子进程永远不会获得 EOF(读取零字节),因为有一个进程可能(但不会)写入管道。出于同样的原因,子进程也必须关闭管道的写入端——如果没有关闭,则有一个进程(本身)可能(但不会)写入管道,因此读取不会 return EOF.

如果将管道的一端复制到标准输出或标准错误,则应关闭该管道的两端。在使用管道的多进程代码中没有对 close() 进行足够的调用是一个常见的错误。偶尔,你会因为马虎而逃脱,但细节因情况而异,通常你不会。