python - 如何通过多处理在单独的 Python 进程中使用用 Cython 包装的外部 C 库?

标签 python c python-3.x cython python-multiprocessing

我在 Cython 中包装了一个小型 C 库,并且可以从 Python 中成功调用它。这是一个简化的示例,表示目前的情况:

# wrapper_module.pyx

cdef extern from "my_c_library.h":
    void function1()
    int function2(int param1, char *param2)

class MyWrapperClass():
    def __init__(self):
        pass
    def do_func1(self):
        function1()
    def do_func2(self, p1, p2):
        function2(p1, p2)

这一切都很好。我现在的目标是在单独的进程中创建和使用 MyWrapperClass 的实例,如下所示:

# my_script.py

import multiprocessing as mp
from wrapper_module import MyWrapperClass

class MyProcess(mp.Process):
    def __init__(self):
        super().__init__()

    def run(self):
        self.mwc = MyWrapperClass()
        self.mwc.do_func1()
        # ... do more

if __name__ == '__main__':
    proc = MyProcess()
    proc.start()

当我运行 my_script.py 时,出现以下错误:

The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). Break on THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC() to debug.

我想我大致理解为什么它不允许将此 cython 模块 fork 到不同的进程中(由于底层 C 库使用的资源)。但一般来说,当我过去遇到这类问题时,无论是在纯 Python 中还是使用 ctypes 并调用 DLL,我都可以通过将所有关键代码放在 run 方法中来解决它MyProcess,导致它只在新派生的进程中初始化。

但是,在这个 Cython 案例中,我不知道如何仅在 fork 进程中包含 cdef extern 代码,以避免此错误。有什么建议吗?

(我在 macOS 10.12 上运行 python 3.6.2)

最佳答案

cdef extern中的代码只是对外部c函数的声明(我们只考虑c),这些声明被放入生成的c文件中(几乎)没有任何变化,与初始化。

我也做了一个相当简单的测试(py3.6 windows):

lib.c:

int add(int a, int b)
{
    return a + b ;
}

mylib.pyx:

cdef extern from "lib.c":
    int _add "add"(int a, int b)

cdef class WrapperClass:
    def add(self, a, b):
        return _add(a, b)

test_lib.py:

from mylib import WrapperClass
import multiprocessing as mp

class MyProcess(mp.Process):
    def __init__(self):
        super().__init__()

    def run(self):
        self.mwc = WrapperClass()
        print(self.mwc.add(1, 2))


if __name__ == "__main__":
    proc = MyProcess()
    proc.start()

运行 python test_lib.py 没有任何问题。也许我的 C 代码太简单了,但我不知道你的 C 函数到底做了什么,myabe 这才是真正的问题。

关于python - 如何通过多处理在单独的 Python 进程中使用用 Cython 包装的外部 C 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46456499/

相关文章:

python - OpenVINO:如何使用推理引擎构建 OpenCV 以启用从模型优化器加载模型

python - 将数据框的值居中

Python requests 库不工作,而 cURL 工作

c - 空终止字符指针

使用 fread 和 fwrite 复制二进制文件

python - 在圆 OpenCV 内绘制文本

python - 取具有相同值的每个元素的平均值的最快方法?

c++ - 是否存在两次包含相同 header 实际上有帮助的情况?

python-3.x - 如何在中间件中使用 `fastapi_another_jwt_auth` 而不是通过 FastAPI 中的依赖注入(inject)?

python-3.x - asyncio 实现了什么样的事件驱动处理模式?