python - 为什么 Python filelock 库在 Windows 而不是 UNIX 上删除锁定文件?

标签 python linux filelock

我正在使用 the filelock module for Python .

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

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

操作系统之间的差异是否有原因?如果没有理由不同,那么这些行为中哪一个更正确?

最佳答案

专门讲py-filelock

filelock用于在 UNIX 上删除锁文件;自 benediktschmitt/py-filelock#31 起,此行为已被删除, 这是指 flock(): removing locked file without race condition? -- 讨论了本答案后面部分描述的相同竞争条件。


为什么一般做法不同

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

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


一个特定的种族例子

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

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

因此,上面说明了在 UNIX 上,删除锁定文件会导致出现竞争条件,其中一个锁似乎同时被两个程序持有。

关于python - 为什么 Python filelock 库在 Windows 而不是 UNIX 上删除锁定文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58098634/

相关文章:

python - 使用Inspect模块执行特定代码

python - 在Python中实现自定义可迭代对象

python:调用 socket.recvfrom() 两次

python - 处理/转置 Pandas 数据框

linux - 我怎样才能杀死管道后台进程?

c++ - 加载自定义 dll + 自定义应用程序失败并显示 : error while loading shared libraries

linux - 如何编写仅构建库的 makefile?

iis-6 - 为什么 SMTP 服务将文件锁定几个小时?

c# - 检查未锁定的文件是否打开

c# - 在 c# 中使用 file.move 时文件锁定...如何停止或修复此问题