在linux中删除打开的文件时,内部会发生什么
我遇到了一些关于在linux中删除打开的文件的问题 然而,当一个进程(称之为在linux中删除打开的文件时,内部会发生什么,linux,file-io,Linux,File Io,我遇到了一些关于在linux中删除打开的文件的问题 然而,当一个进程(称之为a)通过另一个进程B删除打开的文件时,我仍然对RAM中发生了什么感到困惑 让我困惑的是(我的分析可能是错误的,如果是,请纠正我): 当进程打开一个文件时,将在UFDT中为该文件创建一个新条目 当进程删除文件时,指向该文件的所有链接都将消失 特别是,我们没有引用它的inode,因此,它被从GFDT中删除 但是,当修改文件(比如写入文件)时,它必须在磁盘中更新(因为它的页面被修改/弄脏),但由于先前的删除,它在GFDT中没
a
)通过另一个进程B
删除打开的文件时,我仍然对RAM中发生了什么感到困惑
让我困惑的是(我的分析可能是错误的,如果是,请纠正我):
- 当进程打开一个文件时,将在UFDT中为该文件创建一个新条目
- 当进程删除文件时,指向该文件的所有链接都将消失
特别是,我们没有引用它的
,因此,它被从GFDT中删除inode
- 但是,当修改文件(比如写入文件)时,它必须在磁盘中更新(因为它的页面被修改/弄脏),但由于先前的删除,它在GFDT中没有引用,因此我们不知道它的
索引节点
当没有名字并且内核不再使用它时,可能会也可能不会被破坏。我从来没有听说过UFDT和GFDT的首字母缩略词,但是你对系统的看法听起来基本正确。我认为您在描述内核如何管理打开的文件时缺乏一些细节,也许这就是您的困惑所在。我将尝试给出更详细的描述 首先,有三种数据结构用于跟踪和管理打开的文件:
- 每个进程都有一个文件描述符表。此表中的每个条目都存储一个文件描述符和文件描述符状态标志(到目前为止,唯一的标志是
)。文件描述符只是指向文件表条目中的一个条目的指针,下面我将介绍它。O_CLOEXEC
和family返回的整数通常是该文件描述符表的索引-每个进程都有自己的表,这就是为什么open(2)
和family可以为打开不同文件的不同进程返回相同的值open(2)
- 在整个系统中有一个打开的文件表。每个进程的每个文件描述符表项都引用打开的文件表中的其中一个项。对于每个打开的文件,此表中有一个条目:如果两个进程打开同一个文件,则会在此全局表中创建两个条目,即使它是同一个文件。文件表中的每个条目都存储文件状态标志(打开以进行读取、写入、追加等操作)和当前文件偏移量。这就是为什么不同的进程可以同时读取和写入同一文件中的不同偏移量,只要每个进程打开该文件
- 文件表条目中的每个条目还引用vnode表中的一个条目。vnode表是一个全局表,每个唯一文件有一个条目。如果进程A、B和C打开文件D,则只有一个vnode表条目,由所有3个文件表条目引用(在Linux中,实际上没有vnode,而是有一个inode,但让我们保持此描述的通用性和概念性)。vnode条目包含与传统inode几乎相同的信息(文件大小、其他属性等),但它还包含对打开的文件有用的其他信息,例如活动的文件锁、谁拥有它们、它们锁定的文件部分、,此vnode条目还存储指向磁盘上文件数据块的指针
取消链接(2)
。此函数用于取消文件与目录的链接。磁盘中的每个文件索引节点都有指向它的链接数;只有当链接计数达到0且未打开该文件时(对于目录,则为2,因为目录引用自身并由其父目录引用),才会真正删除该文件。事实上,unlink(2)
的手册页非常具体地描述了这种行为:
取消链接-删除名称及其引用的文件
因此,与其将取消链接视为删除一个文件,不如将其视为删除一个文件名,或者它引用的文件
当解除链接(2)
检测到