当我准备考试时,我遇到以下陈述:
如果file1和file2是硬链接的,并且两个进程打开file1和file2, 他们的读/写指针保持不变。
根据答案(没有解释),这是错误。所以我搜索了谷歌,发现了一些不同的东西。
此链接:https://www.usna.edu/Users/cs/wcbrown/courses/IC221/classes/L09/Class.html表示读/写指针位于(系统范围内)打开的文件表中。
但是这个链接http://www.cs.kent.edu/~walker/classes/os.f08/lectures/Walker-11.pdf 表示指针位于每个进程文件表中。
哪一个是真的?
恕我直言,读/写偏移显然必须是“每个进程”属性。如果这是系统范围内的每个文件属性,您可能很容易使其他进程崩溃。这是我的理解,但我宁愿得到知情人士的证实。 我看了 Maurice J. Bach 1986 年 AT&T 出版的书《Unix 操作系统的设计》,我认为这是一个知情来源。
在主题
2.2.1 文件子系统概述中,它说:
...索引节点存储在文件系统中...内核读取它们 操作文件时进入内核inode表5.1 OPEN......内核 包含另外两个数据结构,文件表和用户 文件描述符表。 文件表是一个全局内核 结构,但用户文件描述符表分配给per 进程 ... 文件表 跟踪(读/写)字节 偏移 ...
这与我的陈述相矛盾。但是,可以在主题
,第 92ff 页中阅读说明。图 5.3 显示了一个进程完成了三次打开的示例,其中两次打开同一个文件 /x/y/z(我在这里简化了命名,如下图所示)。
User File
Descriptor Table File Table inode Table
+--------------+ +------------+ +------------+
0| | | | | |
+--------------+ | . | | . |
1| | | . | | . |
+--------------+ | . | | . |
2| | +------------+ | |
+--------------+ +-->| read offset|----+ | |
3| | | +------------+ | | |
+--------------+ | | | | +------------+
4| |---+ | . | +->| inode of |
+--------------+ | . | +--->| /x/y/z |
5| |----+ | . | | +------------+
+--------------+ | +------------+ | | . |
6| |-+ +->| read |----+ | . |
+--------------+ | +------------+ | | | . |
| . | | | . | | | +------------+
| . | | | . | | +->| inode of |
| | | | . | | | /a/b |
+--------------+ | +------------+ | +------------+
+---->|write offset|--+ | . |
+------------+ | . |
| . | | . |
| . | | . |
+------------+ +------------+
最终答案在第94页图5.3下面的文字中:
图5.3展示了
inode表文件表、文件之间的关系 表和用户文件描述符表结构。每个打开 返回一个文件描述符给进程,以及对应的条目 在 用户文件描述符表 指向一个 唯一条目 内核文件表,即使一个文件(/x/y/z)被打开两次.
回答你的问题:读/写偏移量保存在内核
中,而不是在每个进程表中,但是在每个 open() 上分配一个唯一条目。 但是,为什么会有内核
文件表呢?毕竟,读/写偏移量可以存储在每个进程的用户文件描述符表中,而不是存储在内核表中,不是吗? 要理解为什么存在内核
文件表,请考虑 dup() 和 fork() 函数对文件描述符的作用:它们复制打开文件的状态。在同一进程 dup() 中的新文件描述符下,或在新(子)进程中的相同文件描述符(编号)下但在重复的“用户文件描述符表”中。在这两种情况下,复制打开文件的状态包括读/写偏移量。因此,对于这些情况,多个文件描述符将指向单个文件表条目。