【问题标题】:How to load a ctype library in multiple Python processes?如何在多个 Python 进程中加载​​ ctype 库?
【发布时间】:2020-01-08 12:13:36
【问题描述】:

我有一个需要从 Python 调用的 golang 库。我将它构建到.so 库并通过cdll.LoadLibrary() 在Python 中加载它,它运行良好。

现在我需要在我的主进程和multiprocessing.Process() 建立的子进程中使用该库。 (我知道如果我使用线程这不会有问题,但出于某种原因我需要使用 Process。)但是该库在子进程中无法正常工作。它只是不时停止。我的猜测是 lib 中的全局变量只启动一次(在主进程中),因此子进程无法访问这些变量。我通过在 golang 库的 init() 函数中打印一些行来调试它,即使我在两个进程中分别调用 cdll.LoadLibrary(),它也确实只打印一次。

我不知道如何解决这个问题,即如何在子进程中加载​​一个全新的自包含版本的库。 (或者,如果我可以在主进程中加载​​库并让子进程访问对我也有用的库,但这似乎更复杂,我也不知道该怎么做。)

任何建议将不胜感激。

简化代码示例:

from ctypes import cdll
from multiprocessing import Process
...

lib = cdll.LoadLibrary("./go_lib.so")
lib.do_some_thing() # <- works well
...

def worker():
    lib = cdll.LoadLibrary("./go_lib.so")
    lib.do_some_thing() # <- won't work correctly

p = Process(target=worker)
p.start()
p.join()

【问题讨论】:

  • 如果将句柄 (lib) 传递给 worker 会怎样?
  • 如果您只在工作进程中(即不在主进程中)执行LoadLibrary,库是否工作?如果你启动多个进程?
  • @CristiFati 我试过了。它不会起作用。
  • @SamMason 如果我只在工作程序中加载和调用库,它会在子进程中工作。如果我有 2 名工人,他们都可以工作(假设它没有在主进程中加载​​)。
  • @SamMason 实际上,您在这里提出了一个很好的观点:似乎我可以将主进程的工作放到另一个子进程中,因此仅在子进程中调用 lib。这可能是一种解决方法。但这不是一个理想的解决方案,因为我必须确保在主进程中的任何地方都不会调用 lib(这对于维护大型代码库并不容易)。

标签: python subprocess ctypes python-multiprocessing


【解决方案1】:

我建议您面临的问题是由于库无法处理 forks 的程序。您有一些明显的选择:

  1. 仅在子进程中使用该库,例如我的实验
  2. 仅在分叉子进程后在父进程中实例化它。使用Pool 可能会使这更容易,因为进程都是在创建池时分叉的,您可以在需要时在其中运行代码。您可以在initializer 中加载库
  3. 告诉multiprocessing不要分叉,而是告诉spawn processes

【讨论】:

    猜你喜欢
    • 2015-03-26
    • 2022-12-05
    • 2021-03-20
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多