跳转到主要内容

使用POSIX文件锁定确保您的代码不会在多个进程中进行并发执行。

项目描述

这是一个简单的Python 3.4+模块,用于确保您的代码不会在多个进程中并发执行,使用POSIX文件锁定。

可以使用with语法或作为装饰器轻松获取锁。

为什么?

如果您有长时间运行的过程,如果并发执行将导致损坏,那么这个包就是为您准备的。您可以在执行备份、数据库迁移或其他需要在中断时中止的长运行脚本中使用它。

内部工作原理

该模块使用POSIX文件锁定和PID文件

  • 选择一个文件来存储锁信息,通常是/var/lock/py_exclusivelock_yournamehere.lock,称为锁文件,基于您提供的名称。在用作文件名之前,名称会被清理。

  • 如果锁文件已存在并且它包含正在运行的过程的PID(包括当前进程),则会抛出CannotAcquireLock异常。

  • 否则,锁文件将被创建(或覆盖),并将此进程的整数进程ID写入文件。使用POSIX文件锁定(lockf)和以O_EXCL方式打开来防止竞态条件。

  • 当with语句块或装饰函数退出时,锁定文件会被删除。或者在程序退出时,如果使用.forever()(见下文)。

如何使用它

首先安装此包

pip3 install exclusiveprocess

然后在Python文件中导入该包

from exclusiveprocess import Lock, CannotAcquireLock

您可以在with语句中使用它

try:
    with Lock(name="myprocess"):
        print("This block cannot be executed concurrently!")
except CannotAcquireLock:
    print("Well, that's bad.")

或者作为装饰器

# lock name chosen based on __file__
@Lock
def myfunc():
    print("This function cannot be executed concurrently!")

# lock name is "myprocess"
@Lock(name="myprocess")
def myfunc():
    print("This function cannot be executed concurrently!")

名称由您决定。锁是针对名称的。名称是系统全局的(与文件系统一样全局)。

还有一些方便的功能可以帮助您锁定整个程序。

  1. name参数是可选的,默认值为调用Lock函数的模块的文件名(即您的Python源文件),使用inspect.stack(),使得Lock对所有应用程序的调用都是自动排他的。

  2. 当您将可选的die关键字参数设置为True时,如果无法获取锁,Lock会在STDERR上打印错误信息并立即以退出代码1退出进程,而不是抛出异常。

  3. 您可以使用.forever()而不是with或装饰器语法来获取锁,在这种情况下,锁将在程序退出时使用atexit释放。

通过这些功能,您可以在程序开始处放置以下行来使整个程序独占使用

# At program start.
Lock(die=True).forever()
# program exits here if lock could not be acquired

如果同时运行两个这样的程序,您将在STDERR上看到

Another '/home/user/your_script.py' process is already running (pid 27922).

高级

如果您想查看锁定文件存储的位置,可以捕获with对象

with Lock(name="test1") as lock:
    print(lock.lockfile)

# outputs:
/var/lock/py_exclusivelock_test1.lock

Lock类会将每次获取和释放锁都记录到logging.info。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

exclusiveprocess-0.9.4.tar.gz (9.0 kB 查看哈希值)

上传时间 源代码

支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面