不同进程中的相同fd如何指向同一个文件?

Pit*_*kos 30 kernel file-descriptors open-files

假设我有process 1process 2。两者都有一个对应于整数 4 的文件描述符。

然而,在每个进程中,文件描述符 4 指向内核打开文件表中的一个完全不同的文件:

在此处输入图片说明

这怎么可能?文件描述符不应该是打开文件表中记录的索引吗?

jw0*_*013 42

文件描述符,即4在您的示例中,是特定于进程的文件描述符表的索引,而不是打开的文件表。文件描述符条目本身包含内核全局打开文件表中条目的索引,以及文件描述符标志。

  • 作为记录,大多数系统上只有一个“文件描述符标志”,即 close-on-exec 标志。所有其他“per-fd”状态(包括偏移量和访问模式)都是打开文件表条目的一部分。 (2认同)

Gil*_*il' 27

每个进程都有自己的文件描述符表。进程1234中的文件描述符4指向进程1234的表内。进程 5678 中的文件描述符 4 指向进程 5678 的表内。您必须熟悉的一种情况是文件描述符 0、1 和 2,它们对于每个进程是标准输入、标准输出和标准错误,指向这些被重定向到的任何地方。

一个进程可以多次打开同一个文件。这可能会偶然发生,例如,当一个进程的标准输出和标准错误被重定向到同一个终端或同一个文件时。底层文件表条目(例如Linux 的struct file)携带的不仅仅是关于文件的信息;它们还包含打开模式(例如读取或写入)和其他状态(例如标志,例如 close-on-exec)。例如,一个进程可能有一个终端,只在文件描述符 0 上打开读取,而同一个终端只在文件描述符 2 上写入。文件表条目还包含进程在文件中的位置;一个进程可能想要lseek在同一个文件中的两个不同位置,因此将用于dup获取该文件的两个句柄。

  • 这并不完全正确。根据手册页/规范,`dup` 完全符合它在 tin 上所说的:两个结果描述符都指向同一个文件表条目,因此共享相同的偏移量。为了获得 2 个不同的文件表条目,我很确定您需要“打开”文件两次。 (3认同)

Mic*_*jer 8

每个进程都有自己的文件描述符表。就这样。

如果您想深入学习,Richard Stevens在UNIX Network Programming 中对此进行了很好的描述。


Bru*_*ger 7

额外的间接级别不能解决您的问题吗?(“计算机编程中的所有问题都可以通过额外的间接级别来解决” - 一些聪明的灰胡子)。也就是说,每个进程中的小整数最终会成为“打开文件表”中内核空间索引的每个进程数组的索引。

  • [来源](http://www.dmst.aueb.gr/dds/pubs/inbook/beautiful_code/html/Spi07g.html) *明智的灰胡子*很可能是大卫·惠勒。他似乎还说,“*但这通常会产生另一个问题。*”:) (2认同)