我在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时,我收到以下错误:
该进程已分叉,您无法使用此CoreFoundation 功能安全。你必须exec()。打断 的 THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY ___ YOU_MUST_EXEC () 调试。
我想我一般都明白为什么它不允许将这个cython模块分成不同的进程(由于底层C库使用的资源)。但通常当我在过去遇到过这种类型的问题时,无论是纯Python还是使用ctypes并调用DLL,我都可以通过将所有关键代码放在run
MyProcess
方法中来解决它,导致它只在新分叉的进程中初始化。
但是,在这个Cython案例中,我不知道如何仅在分叉进程中包含cdef extern
代码,以避免此错误。有什么建议吗?
(我在macOS 10.12上运行python 3.6.2)
答案 0 :(得分:0)
cdef extern
中的代码只是外部c函数的延迟(我们只考虑c),这些delarations被放入生成的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函数究竟做了什么,真的是真正的问题。