Linux 上 Python 中的系统范围互斥锁
- 2024-10-31 08:38:00
- admin 原创
- 40
问题描述:
在 Linux 上的 Python 中,是否有任何简单的方法可以拥有系统范围的互斥锁?所谓“系统范围”,我的意思是互斥锁将由一组 Python进程使用;这与传统的互斥锁不同,后者由同一进程内的一组线程使用。
编辑:我不确定 Python 的multiprocessing
包是否是我需要的。例如,我可以在两个不同的解释器中执行以下操作:
from multiprocessing import Lock
L = Lock()
L.acquire()
当我在两个不同的解释器中同时执行这些命令时,我希望其中一个挂起。相反,两个都没有挂起;看来它们没有获取相同的互斥锁。
解决方案 1:
“传统”的 Unix 答案是使用文件锁。您可以使用它lockf(3)
来锁定文件的某些部分,以便其他进程无法编辑它;一种非常常见的滥用是将其用作进程之间的互斥锁。python 等效项是fcntl.lockf。
传统上,您将锁定进程的 PID 写入锁定文件,以便可以识别和修复由于持有锁定时进程死亡而导致的死锁。
这样就可以得到想要的结果,因为锁位于全局命名空间(文件系统)中,并且可供所有进程访问。这种方法还有一个好处,即非 Python 程序可以参与锁定。缺点是,您需要一个地方来存放此锁定文件;此外,有些文件系统实际上无法正确锁定,因此存在无法默默实现排除的风险。有得必有失。
解决方案 2:
我的答案与其他答案重叠,但只是为了添加一些人们可以复制粘贴的内容,我经常做这样的事情。
class Locker:
def __enter__ (self):
self.fp = open("./lockfile.lck")
fcntl.flock(self.fp.fileno(), fcntl.LOCK_EX)
def __exit__ (self, _type, value, tb):
fcntl.flock(self.fp.fileno(), fcntl.LOCK_UN)
self.fp.close()
然后将其用作:
print("waiting for lock")
with Locker():
print("obtained lock")
time.sleep(5.0)
为了测试,请touch lockfile.lck
在两个或多个不同的终端(来自同一目录)中运行上述代码。
更新:smwikipedia 提到我的解决方案是特定于 unix 的。我最近需要一个可移植版本,并想出了以下内容,这个想法来自一个随机的github 项目。我不确定 seek() 调用是否需要,但它们存在是因为 Windows API 锁定了文件中的特定位置。如果您不使用文件进行锁定以外的任何其他操作,您可能可以删除搜索。
if os.name == "nt":
import msvcrt
def portable_lock(fp):
fp.seek(0)
msvcrt.locking(fp.fileno(), msvcrt.LK_LOCK, 1)
def portable_unlock(fp):
fp.seek(0)
msvcrt.locking(fp.fileno(), msvcrt.LK_UNLCK, 1)
else:
import fcntl
def portable_lock(fp):
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
def portable_unlock(fp):
fcntl.flock(fp.fileno(), fcntl.LOCK_UN)
class Locker:
def __enter__(self):
self.fp = open("./lockfile.lck")
portable_lock(self.fp)
def __exit__(self, _type, value, tb):
portable_unlock(self.fp)
self.fp.close()
解决方案 3:
尝试ilock库:
from ilock import ILock
with ILock('Unique lock name'):
# The code should be run as a system-wide single instance
...
解决方案 4:
POSIX 标准指定了可用于此目的的进程间信号量。http ://linux.die.net/man/7/sem_overview
Python 中的模块multiprocessing
基于此 API 和其他 API 构建。特别是,multiprocessing.Lock
它提供了跨进程“互斥锁”。http ://docs.python.org/library/multiprocessing.html#synchronization-between-processes
编辑以回答已编辑的问题:
在您的概念证明中,每个进程都在构建一个Lock()
。因此您有两个单独的锁。这就是为什么两个进程都不等待的原因。您将需要在进程之间共享同一个锁。我在文档中链接的部分multiprocessing
解释了如何做到这一点。
解决方案 5:
只需在列表中添加一个,就有posix_ipc库,它有一个Semaphore
类。
计数为 1 的信号量可用作互斥量。为了完成线程三重奏,SystemEvent库也使用posix_ipc
并提供了事件。
我还要指出的是,这也不会轮询您的硬盘!
解决方案 6:
对于能够同步完全独立进程(即包括不属于同一进程树的 Linux 进程)的系统范围互斥锁,只需使用fcntl.flock。我认为使用 Linux 的 /run/shm 文件夹下的内存文件可能会使其运行得更快。
更多详情请见此处。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件