PyEval_InitThreads 何时调用?

5 投票
1 回答
2337 浏览
提问于 2025-04-17 16:08

我对什么时候应该调用 PyEval_InitThreads 有点困惑。一般来说,我知道每当使用非Python线程(也就是在扩展模块中创建的线程)时,都必须调用 PyEval_InitThreads

但是,我不太明白 PyEval_InitThreads 是针对嵌入Python解释器的C程序,还是导入C扩展模块的Python程序,或者两者都适用。

所以,如果我写一个C扩展模块,并且这个模块内部会启动一个线程,我在初始化模块时需要调用 PyEval_InitThreads 吗?

另外,PyEval_InitThreads 会隐式地获取全局解释器锁(GIL)。所以在调用 PyEval_InitThreads 之后,显然必须 释放 这个锁,否则会导致死锁。那么,怎么释放这个锁呢?看了文档后,PyEval_ReleaseLock() 似乎是释放GIL的方法。但是,实际上,如果我在C扩展模块中使用以下代码:

   PyEval_InitThreads();
   PyEval_ReleaseLock();

...那么在运行时Python会中止,并显示:

Fatal Python error: drop_gil: GIL is not locked

那么,在获取了 PyEval_InitThreads 后,怎么才能释放GIL呢?

1 个回答

3

大多数应用程序根本不需要了解 PyEval_InitThreads() 这个东西。

你只有在你的应用程序或扩展模块需要从自己创建的多个线程中调用 Python 的 C 接口时,才需要使用它。

在任何会之后进行 Python C 接口调用的线程中,不要调用 PyEval_ReleaseLock()(除非你在调用之前重新获取锁)。在这种情况下,你最好使用 Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS 这两个宏。

撰写回答