C 我们是否需要显式关闭写入端已关闭的管道的读取端?

C 我们是否需要显式关闭写入端已关闭的管道的读取端?,c,pipe,fgets,inter-process-communicat,C,Pipe,Fgets,Inter Process Communicat,我有下面这个场景 我创建了一个管道 分叉子进程 Child显式关闭管道的读取端,并写入管道的写入端,然后退出而不关闭任何内容(我认为,退出应该代表该子级关闭所有打开的文件/管道描述符) 父级显式关闭管道的写入端,并使用fgets从管道的读取端读取,直到fgets返回NULL。它读起来很完整 现在我的问题是,为什么父级需要在完成读取后显式关闭管道的读取端?一旦从读取端读取了完整的数据,系统就完全删除管道不是很明智吗 我无法在父级中显式关闭读取端,并且在打开更多管道时,文件描述符过多迟早会出错。我的

我有下面这个场景

  • 我创建了一个管道

  • 分叉子进程

  • Child显式关闭管道的读取端,并写入管道的写入端,然后退出而不关闭任何内容(我认为,退出应该代表该子级关闭所有打开的文件/管道描述符)

  • 父级显式关闭管道的写入端,并使用
    fgets
    从管道的读取端读取,直到
    fgets
    返回NULL。它读起来很完整

  • 现在我的问题是,为什么父级需要在完成读取后显式关闭管道的读取端?一旦从读取端读取了完整的数据,系统就完全删除管道不是很明智吗


    我无法在父级中显式关闭读取端,并且在打开更多管道时,
    文件描述符过多
    迟早会出错。我的假设是,一旦管道的写入端关闭,并且从读取端完全读取数据,系统就会自动删除管道。因为你不能从烟斗里抽两次


    那么,一旦数据完全读写结束,系统就不删除管道的基本原理是什么呢?

    您正确地认为,一旦孩子退出,系统将关闭管道的写端。但是,如果子进程
    fork
    s或将写入端的副本传递给另一个进程,则该管道的另一个写入端可能会打开

    系统仍然能够判断管道一端的所有描述符何时都已关闭(无论是显式关闭还是因为所属进程已退出)。关闭管道另一端的描述符仍然没有意义,因为当父进程试图关闭管道另一端的描述符时,这会导致混乱;要么:

    • fd已被系统关闭,在这种情况下,当它试图关闭已关闭的fd时出现错误;或
    • fd被重新使用,更糟糕的是,它正在关闭一个完全不相关的fd

    从系统的角度来看,一旦一端的所有描述符都关闭,它很可能会丢弃管道,因此您不必担心那里的效率低下。更重要的是,用户空间进程应该具有一致的体验,这意味着除非特别请求,否则不会关闭描述符。

    在进程退出之前,系统不会关闭文件描述符。这适用于管道以及任何其他文件描述符

    没有数据的管道(或任何其他文件)和关闭的文件描述符之间有很大的区别。
    关闭文件描述符后,系统可以将其编号重新用于新的文件描述符。然后,当你阅读时,你会得到一些别的东西。因此,关闭文件描述符后,不能再使用它


    现在想象一下,一旦没有更多的数据,系统将自动关闭文件描述符。这将使该号码可供重用,并且后续不相关的打开可能会获得该号码。现在,还不知道没有更多数据的读者将从它认为是管道的东西中读取,但实际上将从另一个文件中读取。

    “因为你不能从管道中读取两次!”???@KerrekSB我的意思是,你可以读取同一管道两次,但会看到第二次EOF,对吗?