【问题标题】:POSIX process and file descriptorsPOSIX 进程和文件描述符
【发布时间】:2013-06-14 02:56:51
【问题描述】:

我是C下进程使用的新手,我有一个与子进程中文件描述符的linux行为有关的问题。

我发现了文件描述符在子进程和父进程之间共享的信息,并且编号为0,1,2的文件描述符是标准输入输出和错误, 所以我认为如果我分叉该进程,我将拥有相同的输入和输出目录,但是当我在子进程中更改它时,它们在父进程中不会更改。我的问题是,它是否适用于每个文件描述符,所以如果我决定让我们说在子进程中覆盖文件描述符编号 100,它在子进程和父进程中会有所不同,或者只有文件描述符 0、1、2 被认为是特殊的。

最好的问候

【问题讨论】:

  • 覆盖文件描述符号是什么意思?
  • 你说的是线程还是进程?
  • 是的,对不起,我的意思是进程,覆盖我的意思是 dup2(fd, 1)
  • 你真的需要阅读像advancedlinuxprogramming.com这样的好材料
  • @BasileStarynkevitch 我刚开始阅读这个主题,但我必须制作 ls | 的管道。 grep | echo 进程,我很惊讶我可以覆盖每个进程中的输入/输出并获得结果,但这对我来说很有意义,但在材料中提到文件描述符由进程与子进程共享

标签: c linux posix


【解决方案1】:

POSIX 线程实际上与fork 没有什么特别的关系,所以我假设您在谈论进程而不是线程。使用线程,没有父子概念,并且共享相同的数据。

对于进程,每个进程都有自己的一组文件描述符,它们是唯一的,一个小的非负数(不是文件句柄, 是 C) 的一个概念。

但是,这些文件描述符都指向共享池中的条目(例如,在内核内部)。这允许所有进程拥有自己的标准输入、输出和错误(描述符 0、1 和 2),但它们可能引用相同的“支持文件”。

因此,当您的进程分叉时,它会获得自己的文件描述符,但它们指向与父进程相同的共享池条目。

如果子级然后关闭其文件描述符并重新打开它以指向其他位置,则只会影响子级,而不影响父级。

假设您有三个进程作为两个分叉的结果,并且进程 C 已关闭并重新打开其标准输出以转到文件。以下是您所处情况的(某种)图形指示:

Individual processes          Shared pool
          +------+            +------------------+
Process A | fd 1 | ----+----> | maps to /dev/tty |
          +------+     |      +------------------+
Process B | fd 1 | ----+
          +------+            +------------------+
Process C | fd 1 | ---------> | maps to new file |
          +------+            +------------------+

对于三个标准描述符来说,这种行为绝不是特殊的,它适用于它们。事实上,描述符不仅在fork 中存在,它们(通常)在exec 中也存在,这使得重定向在类 UNIX 操作系统下工作。如果要在exec 上自动关闭描述符,则必须显式标记它。

【讨论】:

  • 所以如果我得到新的分叉进程,我会从父进程获得文件描述符的副本,但是当我覆盖它们时,我正在更改我的进程结构,对吗?这意味着例如每次进程分叉时文件描述符的数量都会增加?
【解决方案2】:

您可以将文件描述符视为数组的索引。所以标准输入/输出/错误的描述符真的没有什么特别的。

一旦你对进程进行了分叉,就会有两个这样的数组,一个用于父级,一个用于子级。由于被复制,它们一开始都是一样的,但是一旦不同的进程开始打开和关闭其他文件描述符,它们就会开始分歧。

【讨论】:

    【解决方案3】:

    子进程在fork() 时获得父进程打开的文件表的副本,但在那之后父进程或子进程中的任何更改(例如打开新文件描述符)或关闭现有的)不会反映在另一个中。在这方面,文件描述符 0、1 和 2 没有什么特别之处。

    但是请注意,即使打开文件表(即文件描述符集)被复制,这些描述符引用的打开文件也不会被复制。这意味着对打开文件的更新(例如,使用lseek() 更改当前文件位置)会影响这两个进程。

    线程是另一回事。同一个进程中的线程共享同一个打开的文件表,因此一个线程的变化被所有线程看到。同样,文件描述符 0、1 和 2 在这方面没有什么特别之处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      相关资源
      最近更新 更多