当我打电话给PyEval_InitThreads
时,我有点困惑。通常,我知道只要使用非Python线程(即在扩展模块中生成的线程),就必须调用PyEval_InitThreads
。
但是,如果PyEval_InitThreads
用于嵌入Python解释器的C程序,或导入C扩展模块的Python程序,或者两者兼而有,我很困惑。
因此,如果我编写一个内部启动线程的C扩展模块,在初始化模块时是否需要调用PyEval_InitThreads
?
此外,PyEval_InitThreads
implicitly acquires the Global Interpreter Lock。因此,在调用PyEval_InitThreads
之后,可能GIL必须释放,否则将发生死锁。那么你如何释放锁?阅读文档后,PyEval_ReleaseLock()
似乎是释放GIL的方法。但是,实际上,如果我在C扩展模块中使用以下代码:
PyEval_InitThreads();
PyEval_ReleaseLock();
...然后在运行时Python中止:
Fatal Python error: drop_gil: GIL is not locked
那么在用PyEval_InitThreads
获取GIL后如何释放GIL?
答案 0 :(得分:3)
大多数应用程序根本不需要了解PyEval_InitThreads()
。
你应该使用它的唯一一次是你的嵌入应用程序或扩展模块将从多个线程进行Python C API调用,它在Python之外产生。
不要在以后会进行Python C API调用的任何线程中调用PyEval_ReleaseLock()
(除非您在之前重新获取它)。在这种情况下,您应该真正使用Py_BEGIN_ALLOW_THREADS
和Py_END_ALLOW_THREADS
宏。