Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在linux中删除打开的文件时,内部会发生什么_Linux_File Io - Fatal编程技术网

在linux中删除打开的文件时,内部会发生什么

在linux中删除打开的文件时,内部会发生什么,linux,file-io,Linux,File Io,我遇到了一些关于在linux中删除打开的文件的问题 然而,当一个进程(称之为a)通过另一个进程B删除打开的文件时,我仍然对RAM中发生了什么感到困惑 让我困惑的是(我的分析可能是错误的,如果是,请纠正我): 当进程打开一个文件时,将在UFDT中为该文件创建一个新条目 当进程删除文件时,指向该文件的所有链接都将消失 特别是,我们没有引用它的inode,因此,它被从GFDT中删除 但是,当修改文件(比如写入文件)时,它必须在磁盘中更新(因为它的页面被修改/弄脏),但由于先前的删除,它在GFDT中没

我遇到了一些关于在linux中删除打开的文件的问题

然而,当一个进程(称之为
a
)通过另一个进程
B
删除打开的文件时,我仍然对RAM中发生了什么感到困惑

让我困惑的是(我的分析可能是错误的,如果是,请纠正我):

  • 当进程打开一个文件时,将在UFDT中为该文件创建一个新条目
  • 当进程删除文件时,指向该文件的所有链接都将消失 特别是,我们没有引用它的
    inode
    ,因此,它被从GFDT中删除
  • 但是,当修改文件(比如写入文件)时,它必须在磁盘中更新(因为它的页面被修改/弄脏),但由于先前的删除,它在GFDT中没有引用,因此我们不知道它的
    索引节点
问题是为什么打开“已删除”文件的进程仍然可以访问该文件操作系统是如何做到这一点的

编辑UFDT我指的是进程的文件描述符表,其中包含进程打开的文件的文件描述符(每个进程都有自己的UFDT),GFDT是全局文件描述符表,系统中只有一个GFDT(在本例中为RAM)

当一个进程打开一个文件时,将在UFDT中为该文件创建一个新条目 创造

这个奇怪的首字母缩略词是什么?我想你的意思是这个进程有一个文件描述符

当进程删除文件时,指向该文件的所有链接都将消失 特别是,我们没有引用它的inode,因此,它被删除了 来自GFDT

GFDT究竟是什么

但是,在修改文件(比如写入文件)时,必须对其进行更新 在磁盘中(因为它的页面被修改/弄脏),但没有 GFDT中的引用,因为前面的删除,所以我们不知道 这是我的名字

我猜无论这个GFDT是什么,都与“全局”和“文件描述符”有关

因此,所有这些都表明了严重的误解

正如您自己的问题所述,该文件与名称不同。接下来,当您从文件系统中打开某个文件时,它将获得inode的内存中表示形式,并分配一个结构文件对象,该对象稍后指向内存中的inode。最后,更新相关线程的文件描述符表,以在给定偏移量处存储指向struct file对象的指针。偏移量称为文件描述符

就这样。与inode关联的名称数量与内核执行影响inode的读/写操作(或阻止它所代表的文件)的能力无关,只要在删除姓氏之前打开了inode即可


当没有名字并且内核不再使用它时,可能会也可能不会被破坏。

我从来没有听说过UFDT和GFDT的首字母缩略词,但是你对系统的看法听起来基本正确。我认为您在描述内核如何管理打开的文件时缺乏一些细节,也许这就是您的困惑所在。我将尝试给出更详细的描述

首先,有三种数据结构用于跟踪和管理打开的文件:

  • 每个进程都有一个文件描述符表。此表中的每个条目都存储一个文件描述符和文件描述符状态标志(到目前为止,唯一的标志是
    O_CLOEXEC
    )。文件描述符只是指向文件表条目中的一个条目的指针,下面我将介绍它。
    open(2)
    和family返回的整数通常是该文件描述符表的索引-每个进程都有自己的表,这就是为什么
    open(2)
    和family可以为打开不同文件的不同进程返回相同的值
  • 在整个系统中有一个打开的文件表。每个进程的每个文件描述符表项都引用打开的文件表中的其中一个项。对于每个打开的文件,此表中有一个条目:如果两个进程打开同一个文件,则会在此全局表中创建两个条目,即使它是同一个文件。文件表中的每个条目都存储文件状态标志(打开以进行读取、写入、追加等操作)和当前文件偏移量。这就是为什么不同的进程可以同时读取和写入同一文件中的不同偏移量,只要每个进程打开该文件
  • 文件表条目中的每个条目还引用vnode表中的一个条目。vnode表是一个全局表,每个唯一文件有一个条目。如果进程A、B和C打开文件D,则只有一个vnode表条目,由所有3个文件表条目引用(在Linux中,实际上没有vnode,而是有一个inode,但让我们保持此描述的通用性和概念性)。vnode条目包含与传统inode几乎相同的信息(文件大小、其他属性等),但它还包含对打开的文件有用的其他信息,例如活动的文件锁、谁拥有它们、它们锁定的文件部分、,此vnode条目还存储指向磁盘上文件数据块的指针
删除文件包括调用
取消链接(2)
。此函数用于取消文件与目录的链接。磁盘中的每个文件索引节点都有指向它的链接数;只有当链接计数达到0且未打开该文件时(对于目录,则为2,因为目录引用自身并由其父目录引用),才会真正删除该文件。事实上,
unlink(2)
的手册页非常具体地描述了这种行为:

取消链接-删除名称及其引用的文件

因此,与其将取消链接视为删除一个文件,不如将其视为删除一个文件名,或者它引用的文件

解除链接(2)
检测到