5

我对什么时候应该打电话有点困惑PyEval_InitThreads。一般来说,我知道PyEval_InitThreads每当使用非 Python 线程(即在扩展模块中产生的线程)时都必须调用它。

但是,我很困惑PyEval_InitThreads是嵌入 Python 解释器的 C 程序,还是导入 C 扩展模块的 Python 程序,或者两者兼而有之。

那么,如果我编写一个将在内部启动线程的 C 扩展模块,我是否需要PyEval_InitThreads在初始化模块时调用?

此外,PyEval_InitThreads 隐式获取 Global Interpreter Lock。所以在调用之后PyEval_InitThreads,大概 GIL 必须被释放,否则就会出现死锁。那么如何释放锁呢?阅读文档后,PyEval_ReleaseLock()似乎是释放 GIL 的方式。但是,在实践中,如果我在 C 扩展模块中使用以下代码:

   PyEval_InitThreads();
   PyEval_ReleaseLock();

...然后在运行时 Python 中止:

Fatal Python error: drop_gil: GIL is not locked

那么你如何在获得 GIL 后释放它PyEval_InitThreads呢?

4

1 回答 1

3

大多数应用程序根本不需要知道PyEval_InitThreads()

唯一应该使用它的情况是,如果您的嵌入应用程序或扩展模块将从多个线程进行 Python C API 调用,而这些线程在 Python 之外生成

不要调用PyEval_ReleaseLock()任何稍后将进行 Python C API 调用的线程(除非您在这些线程之前重新获取它)。在这种情况下,您应该真正使用Py_BEGIN_ALLOW_THREADSandPy_END_ALLOW_THREADS宏。

于 2013-02-17T19:17:43.717 回答