locking执行文件:Windows确实没有。 为什么?

我注意到当一个文件在Windows(.exe或.dll)上执行时,它被locking,不能被删除,移动或修改。

另一方面,Linux不会locking正在执行的文件,您可以删除,移动或修改它们。

为什么Windows在Linux不锁的时候locking? locking是否有优势?

Linux有一个引用计数机制,所以你可以在执行的时候删除这个文件,只要某个进程(之前打开它)有一个打开的句柄,它就会一直存在。 该文件的目录条目在删除时将被删除,因此无法再打开该文件,但已经使用此文件的进程仍然可以使用该文件。 一旦使用此文件的所有进程终止,文件将被自动删除。

Windows没有这个function,所以它被强制locking文件,直到所有执行的进程完成。

我相信Linux的行为是可取的。 可能有一些深层次的体系结构原因,但是我发现最引人注目的主要原因是,在Windows中,有时你不能删除一个文件,你不知道为什么,而你所知道的是某些进程正在保存它使用。 在Linux中它从来没有发生。

据我所知,linux在运行时locking可执行文件 – 但是,它locking了inode 。 这意味着你可以删除“文件”,但inode仍然在文件系统上,没有任何变化,所有你真正删除的是一个链接。

Unix程序一直使用这种思考文件系统的方式,创build一个临时文件,打开它,删除名称。 你的文件仍然存在,但是这个名字被释放出来供其他人使用,没有人能看到它。

Linux确实locking了这些文件。 如果您尝试覆盖正在执行的文件,将会得到“ETXTBUSY”(文本文件忙)。 但是,您可以删除该文件,并在内核删除该文件的最后一个引用时删除该文件。 (如果机器没有完全closures,这些文件是检查文件系统时“删除的inode具有零d-time”消息的原因,它们没有被完全删除,因为正在运行的进程引用了它们,现在他们是)。

这有一些主要优点,您可以升级正在运行的进程,删除可执行文件,replace它,然后重新启动进程。 即使init可以像这样升级,replace可执行文件,并发送一个信号,它会重新exec()本身,而不需要重新启动。 (这通常是您的包pipe理系统自动完成的,作为升级的一部分)

在Windows下,replace正在使用的文件似乎是一个主要的麻烦,通常需要重新启动以确保没有进程正在运行。

可能会有一些问题,比如如果你有一个非常大的日志文件,并且删除它,但忘记告诉正在login到该文件的进程重新打开该文件,它将保存引用,并且你会想知道为什么你的磁盘没有突然获得更多的自由空间。

你也可以在linux下使用这个技巧来做临时文件。 打开文件,删除它,然后继续使用该文件。 当你的进程退出(无论是什么原因,甚至是电源故障),文件将被删除。

像lsof和fuser这样的程序(或者只是在/ proc // fd中查找)可以告诉你哪个进程打开了一个不再有名字的文件。

我认为linux / unix并没有使用相同的locking机制,因为它们是从一个多用户系统开始build立的 – 这可能会让多个用户使用相同的文件,甚至可能出于不同的目的。

locking是否有优势? 那么,它可能会减less操作系统必须pipe理的指针数量,但现在一天的节省量是可以忽略不计的。 我能想到的locking的最大优点是:保存一些用户可见的模糊性。 如果用户a正在运行二进制文件,并且用户b将其删除,则实际的文件必须坚持到用户A的进程完成。 然而,如果用户B或任何其他用户在文件系统上查找它,他们将无法find它 – 但它将继续占用空间。 对我来说不是一个真正的大问题。

我想在很大程度上,它更多的是向后兼容窗口文件系统的问题。

我认为你对Windows太绝对了。 通常,它不会为可执行文件的代码部分分配交换空间。 相反,它保持对可变的&DLL的locking。 如果再次需要丢弃的代码页,则只需重新加载。 但是用/ SWAPRUN,这些页面保存在交换中。 这用于CD或networking驱动器上的可执行文件。 因此,Windows不需要locking这些文件。

对于.NET,请看Shadow Copy 。

如果一个文件中被执行的代码应该被locking是一个devise决定,并且MS只是决定locking,因为它在实践中有明显的优势:这样你就不需要知道哪个代码在哪个版本中被哪个应用程序使用。 这是Linux默认行为的一个主要问题,大多数人都忽略了这个问题。 如果系统库被replace,你不能很容易地知道哪些应用程序使用这些库的代码,大多数时候你可以得到的最好的是,包pipe理器知道这些库的一些用户,并重新启动它们。 但是,这只适用于一般和知道的东西,也许Postgres和它的库或等等。 更有趣的情况是,如果您针对某些第三方库开发自己的应用程序,并且这些库被replace,因为包pipe理器大部分时间都不知道您的应用程序。 这不仅是本地C代码或其他问题,它可能发生在几乎所有事情上:只要使用带有mod_perl的httpd和一些使用包pipe理器安装的Perl库,并让包pipe理器由于任何原因而更新这些Perl库。 它不会重新启动你的httpd,只是因为它不知道依赖关系。 有很多像这样的例子,只是因为任何文件都可能包含任何运行时在内存中使用的代码,想到Java,Python和所有这些东西。

所以有一个很好的理由认为,默认情况下locking文件可能是一个不错的select。 不过,你不需要同意这个理由。

那么MS做了什么? 他们只是创build了一个API,使调用应用程序有机会决定文件是否被locking,但是他们认为这个API的默认值是给第一个调用应用程序提供一个独占锁。 看看CreateFile及其dwShareMode参数的API。 这就是为什么你可能无法删除某些应用程序正在使用的文件的原因,它只是不关心你的用例,使用默认值,因此得到一个文件的Windows独占locking。

请不要相信有人告诉你一些关于Windows的东西不要使用在手柄上的引用,或者不支持硬链接等等,这是完全错误的。 几乎每个使用HANDLEs的API都会logging它的ref计数行为,而且几乎所有关于NTFS的文章都很容易阅读,因为它支持Hardlinks,而且一直这样做,因为Windows Vista支持Symlinks,而且支持Hardlinks通过提供API来读取给定文件等的所有硬链接来改进。

另外,你可能只想看看用来描述一个文件的结构,例如Ext4与那些有很多共同点的NTFS相比。 两者都使用扩展的概念,它将数据从文件名等属性中分离出来,而inode几乎只是一个较老的,但类似的概念的另一个名称。 维基百科甚至在其文章中列出了两个文件系统。

与Windows上的其他操作系统相比,Windows中的文件locking实际上有很多FUD,就像碎片整理一样。 ;-)这个FUD中的一些可以通过简单地阅读维基百科中的一些内容来排除。

NT变种有

openFiles散

命令,它将显示哪些进程有处理哪些文件。 但是,它确实需要启用系统全局标志“维护对象列表”

openfiles / local /?

告诉你如何做到这一点,而且这样做会导致性能损失。

运行时,可执行文件逐渐映射到内存。 这意味着可执行文件的一部分根据需要加载。 如果在映射所有部分之前将文件换出,可能会导致严重的不稳定。