简体   繁体   English

为什么 Python 文件锁库删除 Windows 上的锁文件而不是 UNIX?

[英]Why does the Python filelock library delete lockfiles on Windows but not UNIX?

I'm using the filelock module for Python .我正在使用filelock的文件锁模块

  • On Windows, when a lock is released, the file that's backing it is deleted.在 Windows 上,当一个锁被释放时,支持它的文件被删除。

  • On UNIX, lock files still exist on the filesystem even after the locks are released.在 UNIX 上,即使释放了锁,文件系统上仍然存在锁文件。

Is there a reason this is different between operating systems?操作系统之间的差异是否有原因? If there isn't a reason for it to differ, which of these behaviors is more correct?如果没有理由让它有所不同,那么这些行为中哪一个更正确?

Speaking Specifically To py-filelock专门针对py-filelock

The filelock library used to delete lockfiles on UNIX;用于删除filelock上的锁文件的文件锁库; this behavior was removed as of benediktschmitt/py-filelock#31 , which refers to flock(): removing locked file without race condition?benediktschmitt/py-filelock#31 ,此行为已被删除,它指的是flock():在没有竞争条件的情况下删除锁定的文件? -- which discusses the same race condition described in a later section of this answer. - 它讨论了本答案后面部分中描述的相同竞争条件。


Why General Practices Differ为什么一般做法不同

The operating-system semantics are different, so different approaches are appropriate in each case.操作系统语义不同,因此在每种情况下都适用不同的方法。 In UNIX, you can delete a file even while there's an open handle, so lockfiles must not be deleted or else two programs can both think they hold the same lock, when in fact they hold locks on completely different inodes which were, at different points in time, referenced under the same filename.在 UNIX 中,即使有打开的句柄,您也可以删除文件,因此不能删除锁定文件,否则两个程序都可能认为它们持有相同的锁,而实际上它们持有完全不同的 inode 上的锁,这些 inode 位于不同的点及时,以相同的文件名引用。

By contrast, default filesystem semantics on Windows make it impossible to delete a file while any program has it open (even though NTFS is powerful enough to support it, it's artificially prevented for backwards compatibility with programs designed around FAT limitations), so on Windows, it's safe to delete a lockfile: If the deletion goes through, that proves that nobody held the lock (or was even in the process of opening the file to later grab a lock on it).相比之下,Windows 上的默认文件系统语义使得在任何程序打开文件时都无法删除文件(即使 NTFS 强大到足以支持它,但为了向后兼容围绕 FAT 限制设计的程序,它被人为地阻止了),所以在 Windows 上,删除锁文件是安全的:如果删除成功,则证明没有人持有锁(或者甚至正在打开文件以稍后获取锁)。


A Specific Race Example一个特定的种族例子

To provide an example of how allowing open files to be unlinked on UNIX makes deleting lockfiles dangerous, consider the following illustration of a common race condition:要提供一个示例,说明允许在 UNIX 上取消链接打开的文件如何使删除锁定文件变得危险,请考虑以下常见竞争条件的图示:

  • Program 1 creates and opens file A1 (under the name "A"), receiving a file handle attached to the inode (the object reflecting the actual file itself, not the directory entry it's attached to) for that newly-created file.程序 1 创建并打开文件 A1(名称为“A”),接收附加到该新创建文件的 inode 的文件句柄(object 反映实际文件本身,而不是它附加到的目录条目)。
  • Program 1 requests an exclusive advisory lock on that handle.程序 1 请求对该句柄的排他咨询锁定。 No other processes have a handle on that same file, so its request for a lock is granted.没有其他进程拥有同一个文件的句柄,因此它的锁请求被授予。
  • Program 2 opens file A1, receiving a second file handle on same.程序 2 打开文件 A1,在其上接收第二个文件句柄。
  • Program 2 requests an exclusive advisory lock on that handle.程序 2 请求对该句柄的排他咨询锁定。 However, because Program A already holds a lock, the request blocks -- which is to say, the program waits for the operating system to pass control back to it later, when the lock can be granted.然而,因为程序 A 已经持有一个锁,所以请求被阻塞——也就是说,程序等待操作系统稍后将控制权交还给它,此时可以授予锁。
  • Program 1 finishes the processes it needed the lock for.程序 1 完成了它需要锁定的进程。
  • Program 1 uses the unlink() syscall to delete the lockfile.程序 1 使用unlink()系统调用来删除锁定文件。 (To be safe on UNIX, just leave this step out). (为了安全起见 UNIX,请忽略此步骤)。 This doesn't delete the file itself (the "inode") until no programs have it open, but it does immediately delete the link to that file from the directory that previously contained it.这不会删除文件本身(“inode”),直到没有程序打开它,但它会立即从先前包含该文件的目录中删除指向该文件的链接。
  • Program 1 closes its handle on the file, thus releasing its lock.程序 1 关闭它对文件的句柄,从而释放它的锁。 The inode is not deleted, because Program 2 still holds a handle. inode 没有被删除,因为 Program 2 仍然持有一个句柄。
  • Program 2 is granted the lock it's been waiting for on the file handle (on the now-unlinked file A1) it opened back before the deletion happened, and is able to resume execution.程序 2 被授予它在删除发生之前打开的文件句柄(在现在未链接的文件 A1 上)上一直在等待的锁,并且能够继续执行。
  • Program 3 creates and opens a new file A2 (with a new and distinct inode) under the same name "A" (which is available because A1's inode is no longer linked to that name), getting a file handle on same.程序 3 创建并打开一个名为“A”的新文件 A2(具有一个新的且不同的 inode)(因为 A1 的 inode 不再链接到该名称,所以该文件可用),并获得一个文件句柄。
  • Program 3 requests a lock on the file handle it owns.程序 3 请求锁定它拥有的文件句柄。 This is immediately granted, because A2 is a different file from A1, and the still-running Program 2 holds a lock on A1, not A2.这是立即授予的,因为 A2 与 A1 是不同的文件,并且仍在运行的程序 2 持有 A1 上的锁,而不是 A2。 Thus, we end up with two programs -- Program 2 and Program 3 -- thinking they hold the same lock.因此,我们最终得到了两个程序——程序 2 和程序 3——认为它们持有相同的锁。

Consequently, the above illustrates how on UNIX , deleting lockfiles allows race conditions wherein a lock can appear to be held by two programs at once.因此,上面说明了在 UNIX 上,删除锁文件如何允许出现竞争条件,其中一个锁似乎同时被两个程序持有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM