我遇到了关于删除linux中已打开文件的this和this个问题
但是,当进程(称为A
)删除另一个进程B
打开的文件时,我仍然对RAM中发生的事情感到困惑。
令我感到困惑的是这个(我的分析可能是错的,如果是这样,请纠正我):
inode
,因此,它将从GFDT中删除inode
。问题为什么“已删除”文件仍可由打开它的进程访问? 操作系统是如何完成的?
编辑 UFDT 我指的是进程的文件描述符表,其中包含由进程打开的文件的文件描述符(每个进程都有自己的UFDT)并且 GFDT 是全局文件描述符表,系统中只有一个GFDT(在我们的例子中是RAM)。
答案 0 :(得分:5)
我从来没有真正听说过那些UFDT和GFDT缩略词,但你对系统的看法听起来大多是正确的。我认为你缺乏关于内核如何管理打开文件的描述的一些细节,也许这就是你的困惑所在。我将尝试提供更详细的说明。
首先,有三种数据结构用于跟踪和管理打开的文件:
O_CLOEXEC
)。文件描述符只是指向文件表条目中的条目的指针,我将在下面介绍。 open(2)
和family返回的整数通常是此文件描述符表的索引 - 每个进程都有其表,这就是为什么open(2)
和family可以为不同的进程返回相同的值文件。删除文件包括调用unlink(2)
。此函数取消链接文件与目录。磁盘中的每个文件inode都有一个指向它的链接数量;如果链接计数达到0并且未打开(或者在目录的情况下为2,因为目录引用自身并且也由其父引用),则仅真正删除该文件。实际上,unlink(2)
的联机帮助页对此行为非常具体:
取消链接 - 删除名称及其引用的文件
因此,不要将取消链接视为删除文件,而是将其视为删除文件名,以及它所引用的文件。
当unlink(2)
检测到存在引用此文件的活动vnode表条目时,它不会从文件系统中删除该文件。什么都没发生。是的,您无法在文件系统上找到该文件。 find(1)
无法找到它。您无法在新流程中打开它。
但文件仍在那里。它不会出现在任何目录条目中。
例如,如果它是一个巨大的文件,并且如果您运行df
或du
,您将看到空间使用情况相同。该文件仍然存在,在磁盘上,您无法访问它。
因此,任何读取或写入都会照常进行 - 文件数据块可通过vnode表条目访问。您仍然可以知道文件大小。和主人。和权限。所有的。一切都在那里。
当进程终止或显式关闭文件时,操作系统会检查inode。如果指向inode的链接数为0,并且这是打开文件的最后一个进程(也通过在vnode表条目中存储链接计数来指示),则清除该文件。
答案 1 :(得分:0)
当进程打开文件时,UFDT中该文件的新条目是 创建
这个奇怪的缩写是什么?我认为你的意思是有问题的过程有一个文件描述符。
当进程删除文件时,该文件的所有链接都将消失 特别是,我们没有引用它的inode,因此它被删除了 来自GFDT
GFDT究竟是什么?
但是,在修改文件(比如写入文件)时,必须更新文件 在磁盘中(因为它的页面被修改/变脏),但它没有 由于早期的删除,GFDT中的引用,所以我们不知道 它的inode。
我猜这个GFDT与“全局”和“文件描述符”有什么关系。
所以,所有这些都表明了严重的误解。
正如您自己的问题所述,该文件与名称不同。接下来,当您从文件系统打开某些内容时,它会获得inode的内存中表示,并分配 struct file 对象,该对象稍后指向内存中的inode。最后,更新相关线程的文件描述符表以将指针存储到给定偏移处的 struct file 对象。偏移量称为文件描述符。
那么。与inode关联的名称数量与内核发出影响inode的读/写(或阻止它所代表的文件)的能力无关,只要它在删除姓氏之前打开它。
当没有名称且内核不再使用它时,可能会或可能不会被删除。