【发布时间】:2013-02-17 00:38:27
【问题描述】:
我有点不知道什么时候应该打电话给PyEval_InitThreads。一般来说,我知道PyEval_InitThreads 必须在使用非 Python 线程(即在扩展模块中产生的线程)时调用。
但是,我很困惑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后如何释放呢?
【问题讨论】:
-
尝试不使用
PyEval_ReleaseLock()。获得 GIL 是有充分理由的;在从 Python 调用其他 C API 函数之前释放它会崩溃。
标签: python c python-3.x python-c-api python-c-extension