锁定执行文件:Windows 有,Linux 没有。为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/196897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Locking Executing Files: Windows does, Linux doesn't. Why?
提问by David Lenihan
I noticed when a file is executed on Windows (.exe or .dll), it is locked and cannot be deleted, moved or modified.
我注意到在 Windows 上执行文件(.exe 或 .dll)时,它被锁定并且无法删除、移动或修改。
Linux, on the other hand, does not lock executing files and you candelete, move, or modify them.
另一方面,Linux 不锁定正在执行的文件,您可以删除、移动或修改它们。
Why does Windows lock when Linux does not? Is there an advantage to locking?
为什么 Windows 锁定而 Linux 不锁定?加锁有好处吗?
回答by Oren Shemesh
Linux has a reference-count mechanism, so you can delete the file while it is executing, and it will continue to exist as long as some process (Which previously opened it) has an open handle for it. The directory entry for the file is removed when you delete it, so it cannot be opened any more, but processes already using this file can still use it. Once all processes using this file terminate, the file is deleted automatically.
Linux 有一个引用计数机制,所以你可以在文件执行时删除它,只要某个进程(之前打开它)有一个打开的句柄,它就会继续存在。当您删除该文件时,该文件的目录条目将被删除,因此无法再打开它,但已经使用该文件的进程仍然可以使用它。一旦使用该文件的所有进程终止,该文件将被自动删除。
Windows does not have this capability, so it is forced to lock the file until all processes executing from it have finished.
Windows 没有此功能,因此它会强制锁定文件,直到从中执行的所有进程都完成。
I believe that the Linux behavior is preferable. There are probably some deep architectural reasons, but the prime (and simple) reason I find most compelling is that in Windows, you sometimes cannot delete a file, you have no idea why, and all you know is that some process is keeping it in use. In Linux it never happens.
我相信 Linux 的行为更可取。可能有一些深层的架构原因,但我认为最引人注目的主要(也是简单)原因是,在 Windows 中,有时您无法删除文件,您不知道为什么,而您只知道某个进程将其保留在用。在 Linux 中它永远不会发生。
回答by Neil Williams
As far as I know, linux doeslock executables when they're running -- however, it locks the inode. This means that you can delete the "file" but the inode is still on the filesystem, untouched and all you really deleted is a link.
据我所知,linux在运行时会锁定可执行文件——但是,它会锁定inode。这意味着您可以删除“文件”,但 inode 仍在文件系统上,未受影响,您真正删除的只是一个链接。
Unix programs use this way of thinking about the filesystem all the time, create a temporary file, open it, delete the name. Your file still exists but the name is freed up for others to use and no one else can see it.
Unix 程序一直使用这种思考文件系统的方式,创建一个临时文件,打开它,删除名称。您的文件仍然存在,但名称已释放供其他人使用,其他人无法看到它。
回答by Neil Williams
Linux does lock the files. If you try to overwrite a file that's executing you will get "ETXTBUSY" (Text file busy). You can however remove the file, and the kernel will delete the file when the last reference to it is removed. (If the machine wasn't cleanly shutdown, these files are the cause of the "Deleted inode had zero d-time" messages when the filesystem is checked, they weren't fully deleted, because a running process had a reference to them, and now they are.)
Linux 确实锁定了文件。如果您尝试覆盖正在执行的文件,您将收到“ETXTBUSY”(文本文件繁忙)。然而,您可以删除该文件,当最后一个引用被删除时,内核将删除该文件。(如果机器没有完全关闭,这些文件是检查文件系统时“已删除的 inode 的 d-time 为零”消息的原因,它们没有被完全删除,因为正在运行的进程有对它们的引用,现在他们是。)
This has some major advantages, you can upgrade a process thats running, by deleting the executable, replacing it, then restarting the process. Even init can be upgraded like this, replace the executable, and send it a signal, and it'll re-exec() itself, without requiring a reboot. (THis is normally done automatically by your package management system as part of it's upgrade)
这有一些主要优点,您可以升级正在运行的进程,方法是删除可执行文件,替换它,然后重新启动该进程。即使 init 也可以像这样升级,替换可执行文件,并向它发送一个信号,它会重新执行()本身,而无需重新启动。(这通常由您的包管理系统作为升级的一部分自动完成)
Under windows, replacing a file that's in use appears to be a major hassle, generally requiring a reboot to make sure no processes are running.
在 Windows 下,替换正在使用的文件似乎是一个主要的麻烦,通常需要重新启动以确保没有进程正在运行。
There can be some problems, such as if you have an extremely large logfile, and you remove it, but forget to tell the process that was logging to that file to reopen the file, it'll hold the reference, and you'll wonder why your disk didn't suddenly get a lot more free space.
可能存在一些问题,例如如果您有一个非常大的日志文件,并且您将其删除,但忘记告诉正在登录该文件的进程重新打开该文件,它会保留引用,您会想知道为什么您的磁盘没有突然获得更多可用空间。
You can also use this trick under linux for temporary files. open the file, delete it, then continue to use the file. When your process exits (for no matter what reason -- even power failure), the file will be deleted.
你也可以在 linux 下使用这个技巧来处理临时文件。打开文件,删除它,然后继续使用该文件。当您的进程退出时(无论出于何种原因——甚至电源故障),该文件都将被删除。
Programs like lsof and fuser (or just poking around in /proc//fd) can show you what processes have files open that no longer have a name.
lsof 和 fuser 之类的程序(或只是在 /proc//fd 中闲逛)可以显示哪些进程打开了不再具有名称的文件。
回答by MSalters
I think you're too absolute about Windows. Normally, it doesn't allocate swap space for the code part of an executable. Instead, it keeps a lock on the excutable & DLLs. If discarded code pages are needed again, they're simply reloaded. But with /SWAPRUN, these pages are kept in swap. This is used for executables on CD or network drives. Hence, windows doesn't need to lock these files.
我认为您对 Windows 过于绝对。通常,它不会为可执行文件的代码部分分配交换空间。相反,它会锁定可执行文件和 DLL。如果再次需要丢弃的代码页,只需重新加载它们。但是使用 /SWAPRUN,这些页面会保留在交换中。这用于 CD 或网络驱动器上的可执行文件。因此,windows 不需要锁定这些文件。
For .NET, look at Shadow Copy.
对于 .NET,请查看Shadow Copy。
回答by Eric Tuttleman
I think linux / unix doesn't use the same locking mechanics because they are built from the ground up as a multi-user system - which would expect the possibility of multiple users using the same file, maybe even for different purposes.
我认为 linux / unix 不使用相同的锁定机制,因为它们是作为多用户系统从头开始构建的 - 这会期望多个用户使用同一文件的可能性,甚至可能用于不同的目的。
Is there an advantage to locking? Well, it could possibly reduce the amount of pointers that the OS would have to manage, but now a days the amount of savings is pretty negligible. The biggest advantage I can think of to locking is this: you save some user-viewable ambiguity. If user a is running a binary file, and user b deletes it, then the actual file has to stick around until user A's process completes. Yet, if User B or any other users look on the file system for it, they won't be able to find it - but it will continue to take up space. Not really a huge concern to me.
加锁有好处吗?好吧,它可能会减少操作系统必须管理的指针数量,但现在节省的数量几乎可以忽略不计。我能想到的锁定的最大优点是:您可以节省一些用户可见的歧义。如果用户 a 正在运行一个二进制文件,而用户 b 删除了它,那么实际文件必须一直存在,直到用户 A 的进程完成。然而,如果用户 B 或任何其他用户在文件系统上查找它,他们将无法找到它 - 但它会继续占用空间。对我来说并不是一个很大的问题。
I think largely it's more of a question on backwards compatibility with window's file systems.
我认为主要是与窗口文件系统的向后兼容性问题。
回答by Thorsten Sch?ning
If executed code in a file should be locked or not is a design decision and MS simply decided to lock, because it has clear advantages in practice: That way you don't need to know which code in which version is used by which application. This is a major problem with Linux default behaviour, which is simply ignored by most people. If system wide libs are replaced, you can't easily know which apps use code of such libs, most of the times the best you can get is that the package manager knows some users of those libs and restarts them. But that only works for general and well know things like maybe Postgres and its libs or such. The more interesting scenarios are if you develop your own application against some 3rd party libs and those get replaced, because most of the times the package manager simply doesn't know your app. And that's not only a problem of native C code or such, it can happen with almost everything: Just use httpd with mod_perl and some Perl libs installed using a package manager and let the package manager update those Perl libs because of any reason. It won't restart your httpd, simply because it doesn't know the dependencies. There are plenty of examples like this one, simply because any file can potentially contain code in use in memory by any runtime, think of Java, Python and all such things.
文件中执行的代码是否应该被锁定是一个设计决定,而 MS 只是决定锁定,因为它在实践中具有明显的优势:这样你就不需要知道哪个应用程序使用哪个版本的哪个代码。这是 Linux 默认行为的一个主要问题,大多数人都忽略了这一点。如果系统范围的库被替换,您就无法轻易知道哪些应用程序使用了这些库的代码,大多数情况下,您能得到的最好结果是包管理器知道这些库的一些用户并重新启动它们。但这仅适用于一般和众所周知的事情,例如 Postgres 及其库等。更有趣的场景是,如果您针对某些 3rd 方库开发自己的应用程序,并且这些库被替换,因为大多数时候包管理器根本不知道您的应用程序。然后' 这不仅是本机 C 代码等的问题,几乎所有事情都可能发生:只需将 httpd 与 mod_perl 和一些使用包管理器安装的 Perl 库一起使用,并让包管理器因任何原因更新这些 Perl 库。它不会重新启动您的 httpd,仅仅是因为它不知道依赖项。有很多这样的例子,仅仅是因为任何文件都可能包含任何运行时在内存中使用的代码,想想 Java、Python 和所有这些东西。
So there's a good reason to have the opinion that locking files by default may be a good choice. You don't need to agree with that reasons, though.
所以有一个很好的理由认为默认情况下锁定文件可能是一个不错的选择。不过,您不需要同意这些理由。
So what did MS do? They simply created an API which gives the calling application the chance to decide if files should be locked or not, but they decided that the default value of this API is to provide an exclusive lock to the first calling application. Have a look at the API around CreateFileand its dwShareMode
argument. That is the reason why you might not be able to delete files in use by some application, it simply doesn't care about your use case, used the default values and therefore got an exclusive lock by Windows for a file.
那么MS做了什么?他们只是创建了一个 API,让调用应用程序有机会决定文件是否应该被锁定,但他们决定这个 API 的默认值是为第一个调用应用程序提供排他锁。查看有关CreateFile的 API及其dwShareMode
参数。这就是为什么您可能无法删除某些应用程序正在使用的文件的原因,它根本不关心您的用例,使用默认值并因此获得了 Windows 对文件的独占锁定。
Please don't believe in people telling you something about Windows doesn't use ref counting on HANDLEs or doesn't support Hardlinks or such, that is completely wrong. Almost every API using HANDLEs documents its behaviour regarding ref counting and you can easily read in almost any article about NTFS that it in deed does support Hardlinks and always did. Since Windows Vista it has support for Symlinks as well and the Support for Hardlinks has been improved by providing APIs to read all of those for a given fileetc.
请不要相信有人告诉您有关 Windows 的某些内容不使用对句柄的引用计数或不支持硬链接等,这是完全错误的。几乎每个使用 HANDLE 的 API 都记录了它关于引用计数的行为,您可以轻松地在几乎所有关于 NTFS 的文章中阅读它确实支持硬链接并且一直支持。从 Windows Vista 开始,它也支持符号链接,并且通过提供 API 来读取给定文件等的所有内容,改进了对硬链接的支持。
Additionally, you may simply want to have a look at the structures used to describe a file in e.g. Ext4compared to those of NTFS, which have a lot in common. Both work with the concept of extents, which separates data from attributes like file name, and inodes are pretty much just another name for an older, but similar concept of that. Even Wikipedia lists both file systems in its article.
此外,您可能只想看看用于描述文件的结构,例如Ext4与NTFS的结构相比,它们有很多共同点。两者都使用范围的概念,它将数据与文件名等属性分开,而 inode 几乎只是旧的但类似概念的另一个名称。甚至 Wikipedia 在其文章中都列出了这两种文件系统。
There's really a lot of FUD around file locking in Windows compared to other OSs on the net, just like about defragmentation. Some of this FUD can be ruled out by simply reading a bit on the Wikipedia.
与网络上的其他操作系统相比,Windows 中的文件锁定确实存在很多 FUD,就像碎片整理一样。只需在Wikipedia上阅读一些内容,就可以排除其中的某些 FUD 。
回答by Ken Netherland
Executables are progressively mapped to memory when run. What that means is that portions of the executable are loaded as needed. If the file is swapped out prior to all sections being mapped, it could cause major instability.
可执行文件在运行时逐渐映射到内存。这意味着根据需要加载可执行文件的部分。如果在映射所有部分之前换出文件,则可能会导致严重的不稳定。
回答by spender
NT variants have the
NT 变体具有
openfiles
打开文件
command, which will show which processes have handles on which files. It does, however, require enabling the system global flag 'maintain objects list'
命令,它将显示哪些进程对哪些文件具有句柄。但是,它确实需要启用系统全局标志“维护对象列表”
openfiles /local /?
打开文件 / 本地 /?
tells you how to do this, and also that a performance penalty is incurred by doing so.
告诉您如何执行此操作,以及执行此操作会导致性能损失。