如何在Linux中在Python进程之间锁定目录?

8
我有两个(或更多)正在运行的Python进程,想要创建类似于互斥排除的概念来保护共享资源。在这种情况下,“共享资源”是一个目录。我应该如何最轻松/标准等地实现互斥锁?每个进程都同意检查一个隐藏的.lock文件,如果存在,则将其PID追加为新行,然后在访问文件时弹出其PID。

我基本上只想清空一个目录,并确保在我清空它时没有其他进程尝试读取或写入它。

是否有一种标准的Linux方法可以做到这一点?也许有些东西我可以从Python中用shell命令执行?


你想确保没有其他进程或没有其他Python进程可以从该目录读写吗? - user559633
理想情况下,除了Python进程之外,不需要其他进程。这样我就可以控制它们查找的内容,如果需要的话。但我希望能够找到一个预先制作的解决方案,因为这似乎是一个常见的需求,而且不特定于Python或我的应用程序。 - tarabyte
2个回答

5

Linux

Linux有两种标准的锁类型:建议性锁定(在POSIX中指定)和强制性锁定(仅适用于Linux)。

然而,它们都只能应用于文件,而不能应用于目录。所以是的,你需要一个锁文件。这意味着所有用户都应该知道锁文件并在访问目录之前获取锁。因此,强制锁定在这里将无济于事,你需要使用建议性锁定。

Linux有三种建议性文件锁:

  • flock(2)(在POSIX中指定);
  • POSIX记录锁,请参见“fcntl(2)”中的“建议记录锁定”部分,以及lockf(3)封装器(都在POSIX中指定);
  • 打开文件描述符锁,请参见fcntl(2)(Linux特有,在最近的内核版本中可用)。

Python

在Python中,通过fcntl模块可以使用flock()lockf()fcntl()函数。还有一个flock模块,它为fcntl.flock函数添加了上下文管理器支持。

下面是一个示例:

import flock

with open('/my/dir/lockfile', 'w') as fp:
    with flock.Flock(fp, flock.LOCK_EX) as lock:
        pass # exclusive lock is acquired here

PS.

使用这种方法,如果随机进程不知道你的锁文件,就无法防止它访问你的目录。可能可以使用FUSE实现支持强制目录锁定的文件系统,但我不知道是否有这样的实现。


2
你可以在目录上很好地应用咨询锁,请参见如何在Linux机器上使用C锁定目录。使用os.open()获取目录的文件句柄。 - Martijn Pieters
唯一的缺点是你没有一个记录进程信息的地方(.lock文件或符号链接可以提供一个放置元数据的位置)。 - Martijn Pieters

3

您可以对目录应用群集锁(flock lock)。它是建议性的(它无法阻止不关心锁定并触及目录的进程)。该锁将持续到您的程序终止。代码非常简单。

lockfd = os.open('.',os.O_RDONLY)
fcntl.flock(lockfd,fcntl.LOCK_EX | fcntl.LOCK_NB)

如果我理解man手册的内容正确,那么您只需执行以下操作即可解锁它。
os.close(lockfd)

但我还没有测试过这一点,因为在我的应用程序中,希望锁定整个脚本的运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接