进程间通信资源锁的最佳方式

haa*_*oll 4 python process

我有两个 python 程序,它们应该并行运行并执行相同的操作:

  1. 从磁盘读取并解压缩数据(大约需要 1 分钟)
  2. 处理数据(大约需要2-3分钟)
  3. 将数据发送到数据库(大约需要3-5分钟)

正如您所看到的,最好以一种方式同步两个实例的执行,其中一个执行处理器密集型步骤 1 和 2(实现是多线程的,因此 CPU 实际上可以达到最大),而另一个则执行I/O 密集型步骤 3,反之亦然。

我的第一个想法是使用锁文件,每个进程在进入第 3 阶段时都会获取该锁文件,并在完成阶段后释放它。因此,另一个进程将等待锁被释放,然后在进入阶段 3 时设置它。但是,这似乎是一种非常麻烦的方法。此外,系统应该在无人监管的情况下运行数天或数周,并能够从错误、计划重启或电源故障中恢复。特别是在最后一种情况下,锁文件可以简单地锁定所有内容。

有没有更优雅的方式来在两个进程之间传达锁定?或者我应该使用锁文件并尝试实现一些智能清理功能以防止发生死锁?

Ger*_*erd 5

似乎每个解决方案都有一些缺点 - 某些机制或模块并非在所有平台上都可用(即仅限 Linux 或仅限 Windows),或者您可能会遇到基于文件系统的方法的错误恢复问题(正如您已经指出的那样)在你的问题中)。

以下是一些可能选项的列表:

使用Python的multiprocessing模块

这允许您创建像这样的锁:

lock = multiprocessing.Lock()
Run Code Online (Sandbox Code Playgroud)

并像这样获取和释放它:

lock.acquire() 
# do something
lock.release() 
Run Code Online (Sandbox Code Playgroud)

这是一个完整的例子。

优点:使用简单;跨平台;没有错误恢复问题。

缺点:由于您当前有两个独立的程序,因此您必须重新排列代码才能从同一个 python 模块启动两个进程。

使用fnctl(Linux)

对于 Linux/Unix 系统,fcntl(带有fcntl.flock())可用作 python 模块。这是基于锁文件的。

另请参阅此讨论以及我在此重复的一些建议:

  • 将锁定进程的进程 ID 写入文件,以便能够识别并修复可能的死锁。
  • 将锁定文件放在临时位置或 RAM 文件系统中。

缺点:不跨平台,仅适用于 Linux/Unix 系统。

使用posix_ipc(Linux)

对于 Linux/Unix 系统,有python_ipc(带有一个Semaphore类)可用作 python 模块。

优点:不基于文件系统,不存在错误恢复问题。

缺点:不跨平台,仅适用于 Linux/Unix 系统。

使用msvcrt(Windows)

对于 Windows 系统,有msvcrt(带msvcrt.locking())可用作 python 模块。

另请参阅此讨论

缺点:不跨平台,仅适用于 Windows 系统。

使用第三方库

您可能想查看以下 python 库: