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

Sen*_*r M 8 python linux filelock

我正在使用Python模块filelock

  • 在 Windows 上,当释放锁时,支持该锁的文件将被删除。

  • 在 UNIX 上,即使锁被释放后,锁文件仍然存在于文件系统上。

操作系统之间存在差异是否有原因?如果没有理由不同,那么以下哪种行为更正确?

Cha*_*ffy 8

具体讲到py-filelock

用于删除 UNIX 上的锁定文件的filelock库;从 开始,此行为已被删除,它指的是flock():在没有竞争条件的情况下删除锁定的文件?- 它讨论了本答案后面部分中描述的相同竞争条件。benediktschmitt/py-filelock#31


为什么一般做法有所不同

操作系统语义不同,因此每种情况都适用不同的方法。在 UNIX 中,即使存在打开的句柄,您也可以删除文件,因此不得删除锁文件,否则两个程序都可以认为它们持有相同的锁,而实际上它们在完全不同的 inode 上持有锁,这些 inode 在不同的点上及时在同一文件名下引用。

相比之下,Windows 上的默认文件系统语义使得在任何程序打开文件时都无法删除该文件(即使 NTFS 足够强大来支持它,但为了向后兼容围绕 FAT 限制设计的程序,它被人为阻止),因此在 Windows 上,删除锁定文件是安全的:如果删除成功,则证明没有人持有该锁(或者甚至正在打开文件以稍后获取其锁定)。


一个具体的比赛例子

为了提供一个示例来说明在 UNIX 上允许打开的文件取消链接如何导致删除锁定文件变得危险,请考虑以下常见争用条件的说明:

  • 程序 1 创建并打开文件 A1(名称为“A”),接收附加到该新创建文件的索引节点(反映实际文件本身的对象,而不是它附加到的目录项)的文件句柄。
  • 程序 1 请求该句柄上的独占咨询锁。没有其他进程拥有同一文件的句柄,因此它的锁定请求被授予。
  • 程序 2 打开文件 A1,并接收该文件的第二个文件句柄。
  • 程序 2 请求该句柄上的独占咨询锁。然而,由于程序 A 已经持有锁,因此该请求会被阻塞——也就是说,程序等待操作系统稍后将控制权传回给它,此时可以授予锁。
  • 程序 1 完成了它需要锁的进程。
  • 程序 1 使用unlink()系统调用来删除锁定文件。(为了在 UNIX 上安全起见,请忽略此步骤)。在没有程序打开该文件之前,这不会删除文件本身(“inode”),但它会立即从先前包含该文件的目录中删除指向该文件的链接。
  • 程序 1 关闭该文件的句柄,从而释放其锁。该 inode 没有被删除,因为程序 2 仍然持有一个句柄。
  • 程序 2 被授予在删除发生之前打开的文件句柄(现在未链接的文件 A1 上)一直在等待的锁,并且能够恢复执行。
  • 程序 3 创建并打开一个同名“A”(该文件可用,因为 A1 的索引节点不再链接到该名称)下的新文件 A2(具有新的且不同的索引节点),并获取该文件句柄。
  • 程序 3 请求对其拥有的文件句柄进行锁定。这会立即被授予,因为 A2 与 A1 是不同的文件,并且仍在运行的程序 2 持有 A1 上的锁,而不是 A2 上的锁。因此,我们最终得到两个程序——程序 2 和程序 3——认为它们持有相同的锁。

因此,上面说明了在 UNIX 上,删除锁文件如何允许竞争条件,其中锁可能看起来同时由两个程序持有。