同一fd在不同进程中如何指向同一文件?


25

说我有流程1流程2。两者都有对应于整数4的文件描述符。

但是,在每个过程中,文件描述符4指向内核的“打开文件表”中的完全不同的文件:

在此处输入图片说明

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


1
好问题!我的猜测是文件描述符已翻译,因此4两个进程中的fd 都与它自己的打开fd数有关。Fd 0-2(stdin,stdout,sdterr)始终为新进程打开,并且编号不只为该进程保留。


@ jw013我认为这听起来很熟悉。\ @Pithikos这不是重复的吗?
Michael Mrozek

1
这是一个很差的图表-它应该显示文件描述符4表示左侧文件描述符表的第四个条目 [嗯,第五个,它从零开始计数],而不是包含“ 4”的条目。实际的“ 4”位于包含该数字的用户空间变量中。另一个问题中的图表要好得多。
Random832

2
@ Random832好吧,如果我知道哪个图表是正确的,那么我可能永远不会提出这个问题。
Pithikos

Answers:


35

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


2
为了记录,在大多数系统上只有一个“文件描述符标志”,即“执行时关闭”标志。所有其他“每fd”状态(包括偏移量和访问模式)是打开文件表条目的一部分。
Random832

24

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

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


2
这并不完全正确。根据手册页/规范,dup完全按照其说明进行操作:两个生成的描述符都指向相同的文件表条目,因此共享相同的偏移量。为了获得2个不同的文件表条目,我很确定您需要open对该文件进行两次。
jw013 2011年

@Gilles“进程1234中的文件描述符4指向进程1234的表内部”。你是哪张桌子?据我所知,该过程中唯一的表是文件描述符表,其中每个记录都指向内核的单个“ 打开文件表”
Pithikos 2012年



7

额外的间接级别是否可以解决您的问题?(“计算机编程中的所有问题都可以通过更高级别的间接解决”-明智的白胡子)。也就是说,每个进程中的小整数最终都作为进入“打开文件表”的内核空间索引的每个进程数组的索引。


2
明智樽可能David Wheeler的。他似乎也说过:“ 但这通常会带来另一个问题。 ” :)
jw013 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.