【问题标题】:Behavior of a pipe after a fork()fork() 之后管道的行为
【发布时间】:2011-01-26 14:10:28
【问题描述】:

在 UNIX 环境中的高级编程中阅读有关管道的信息时,我注意到在分叉之后,父级可以close() 管道的读取端,并且它不会关闭子级的读取端。当一个进程分叉时,它的文件描述符会被保留吗?

我的意思是,在分叉之前,管道读取文件描述符的保留计数为 1,在分叉之后为 2。当父关闭其读取端时,fd 变为 1,并为子保持打开状态.这基本上是正在发生的事情吗?常规文件描述符是否也会出现这种行为?

【问题讨论】:

    标签: c unix fork pipe


    【解决方案1】:

    答案是肯定的,肯定的(这同样适用于所有文件描述符,包括套接字之类的东西)。

    fork() 调用中,子进程会获得每个文件描述符的单独副本,每个文件描述符的行为都像是由dup() 创建的。 close() 仅关闭传递的特定文件描述符 - 例如,如果您执行 n2 = dup(n); close(n);,则 n 所指的文件(管道、套接字、设备...)保持打开状态 - 这同样适用于由fork() 复制的文件描述符。

    【讨论】:

    • 正是我想要的。非常感谢。
    【解决方案2】:

    是的,fork 会复制所有打开的文件描述符。

    所以对于一个典型的管道,一个2槽数组(int fd[2]),fd[0]对于父子是一样的,fd[1]也是一样。

    您可以在完全不分叉的情况下创建管道,并通过在一个进程中使用 fd[0] 和 fd[1] 对自己进行读/写。

    【讨论】:

      【解决方案3】:

      正如人们可以在手册页上看到的那样,fork()

      子进程应该有自己的父文件副本 描述符。每个孩子的档案 描述符应指相同的 打开文件描述 对应的文件描述符 父母。

      所以是的,孩子拥有父母文件描述符的精确副本,并且指的是所有这些,包括打开的文件。

      【讨论】:

      • ...除非你对opengroup.org/onlinepubs/009695399/functions/… 做了一些诡计(你不应该这样做,这不是它的用途)
      • 当然,但是您发布的不是fork(),而是它的一个变体。
      • 不,我的意思是pthread_atfork 可以将程序在fork 时间的操作更改为(例如)包括关闭文件描述符。但默认情况下不会发生这种情况,无论如何滥用该接口是一件奇怪的事情。
      • 但是你 fork() 两次然后写给孩子会发生什么。哪个会读它们?两个都?第一个调用read?如果它们当前都在读取时被阻止怎么办?
      猜你喜欢
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多