POSIX进程和文件描述符

时间:2013-06-14 02:56:51

标签: c linux posix

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

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

祝你好运

3 个答案:

答案 0 :(得分:7)

POSIX线程实际上与fork没什么关系,所以我假设你在讨论进程而不是线程。对于线程,没有父和子的概念,并且两者共享相同的数据。

对于进程,每个进程都有自己的一组文件描述符,它们是唯一的,一个小的非负数(不是文件句柄,< / em>这是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上自动关闭描述符,则必须明确标记描述符。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

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