3.10 文件共享
UNIX 系统支持在不同进程见共享打开文件。在介绍 dup 函数之前,先要说明这种共享。
内核使用 3 种数据结构表示打开文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能的影响。
- 每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:
a. 文件描述符标志(close_on_exec);
b. 指向一个文件表项的指针。 - 内核为所有打开文件维持一张文件表。每个文件表项包含:
a. 文件状态标志(读、写、添写、同步和非阻塞等);
b. 当前文件偏移量;
c. 指向该文件 v 节点表项的指针。 - 每个打开文件(或设备)都有一个 v 节点(v-node)结构。v 阶段包含了文件类型和对此文件进行各种操作函数的指针。对于大多数文件,v 节点还包含了该文件的 i 节点(i-node,索引节点)。这些信息是在打开文件时从磁盘上读入内存的。所以,文件的所有相关信息都是随时可用的。
Linux 没有使用 v 节点,而是使用了通用 i 节点结构。
我们忽略了哪些不影响讨论的实现细节。例如,打开文件描述符表可存放在用户空间,而非进程表中。这些表也可以用多种方式实现,不必一定是数组。
下图显示了一个进程对应的 3 张表之间的关系。该进程有两个不同的打开文件:一个文件从标准输入打开(文件描述符 0),另一个从标准输出打开(文件描述符为 1)。
如果两个独立进程各自打开了同一个文件,则有下图关系:
我们假定第一个进程在文件描述符 3 上打开该文件,而另一个进程在文件描述符 4 上打开该文件。打开该文件的每一个进程都获得自己的文件表项,但对一个给定的文件只有一个 v 节点表项。之所以每个进程都获得自己的文件表项,是因为这可以是每个进程都有它自己的对该文件的当前偏移量。