Answers:
原因是Unix在执行时不会锁定可执行文件,即使它像Linux一样,该锁定也适用于inode,而不适用于文件名。这意味着即使文件已被删除(实际上未链接)并由具有相同名称的新文件替换(实际上是软件包更新所做的)后,保持打开状态的进程仍在访问相同(旧)数据。
这是Unix和Windows之间的主要区别之一。后者无法更新被锁定的文件,因为它缺少文件名和inode之间的层,这使更新或什至安装某些软件包变得很麻烦,因为它通常需要完全重新启动。
可执行文件通常打开一次,附加到文件描述符,并且在单个执行期间重新打开二进制文件时没有文件描述符。例如,如果执行bash
,exec()
通常仅/bin/bash
在调用时为一次指向的索引节点创建文件描述符。
这通常意味着,对于在执行过程中不尝试重新读取自身的简单二进制文件(通过使用调用它们的路径),缓存的内容将作为悬挂的inode保持有效。这意味着该可执行文件实际上是先前版本的副本。
在更复杂的情况下,这可能会引起问题。例如,配置文件可以升级并随后重新读取,或者程序可以通过其执行路径重新执行自身。如果程序是互连的,并且在升级之前执行一个程序,然后在升级之后执行一个程序(可能是第一个程序执行),则也会出现问题。对于某些库也是如此。
但是,对于简单的用例,无需重新启动过程即可安全升级。
bash
二进制文件大约有200个4K页,请确保在一次平均会话中都不会使用它们。
ialloc()
读取时读取内核结构,而不是页面本身的内存映射。我是否不认为在现代ext *文件系统上,inode最终在内核(以及VM子系统内部)是一致的?