Python 3.11 C扩展模块加载触发GIL致命错误求助
问题分析与解决:Python C扩展加载时GIL错误
错误信息
_Fatal Python error: _PyInterpreterState_GET: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL)
问题原因
你的代码逻辑本身无错误,但Python 3.11及更高版本更改了模块初始化函数的GIL持有规则:早期版本中PyInit_xxx会自动持有GIL,而3.11开始初始化函数默认不持有GIL。你在PyInit_bob中调用的PyErr_NewException、PyModule_AddObject等Python API都要求必须持有GIL,因此触发了致命错误。
修复方案
在模块初始化函数开头手动获取GIL,完成所有Python API操作后释放GIL,修改后的PyInit_bob函数如下:
PyMODINIT_FUNC PyInit_bob(void) { PyObject* m = NULL; // 手动获取GIL,保存当前状态 PyGILState_STATE gstate = PyGILState_Ensure(); m = PyModule_Create(&BobModule); if (m == NULL) { PyGILState_Release(gstate); return NULL; } BobError = PyErr_NewException("bob.error", NULL, NULL); Py_XINCREF(BobError); if (PyModule_AddObject(m, "error", BobError) < 0) { Py_XDECREF(BobError); Py_CLEAR(BobError); Py_DECREF(m); m = NULL; } // 释放GIL,恢复之前的状态 PyGILState_Release(gstate); return m; }
关键说明
PyGILState_Ensure():强制获取GIL,即使当前线程没有Python线程状态,也会创建临时状态保证API可正常调用。PyGILState_Release(gstate):恢复调用PyGILState_Ensure()之前的GIL状态,释放持有的锁。- 所有涉及Python对象创建、操作的代码必须放在GIL持有区间内。
内容的提问来源于stack exchange,提问作者glzbcrt
相关产品推荐
相关产品推荐

