【已解决】Cython中获取GIL失败Fatal Python error: take_gil: NULL tstate

今天封装一个CTP的库,我把所有的回调函数转发给python对象,如下代码:

#define X_CALL(op) \
	do { \
	    PyGILState_STATE gilstate = PyGILState_Ensure(); \
		tid = PyThread_get_thread_ident(); \
		if ((op) == -1) PyErr_Print(); \
		PyGILState_Release(gilstate); \
	} while (0)

然后运行代码中,回调函数转发的时候,运行报错:

Fatal Python error: take_gil: NULL tstate

参考Cython的官方文档GIL相关部分:

If the callback may be called from another non-Python thread, care must be taken to initialize the GIL first, through a call to PyEval_InitThreads()

如果回调函数从另外一个非Python线程里返回,那么一定要先初始化GIL,通过:

PyEval_InitThreads()函数

具体可以参考如下链接了解更多:

(这个问题专业点来讲叫:Non-Python created threads

http://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#acquiring-the-gil

http://bugs.python.org/issue20891

http://bugs.python.org/issue19576

http://bugs.python.org/issue26003

http://bugs.python.org/issue20891

http://www.cnblogs.com/cbscan/articles/3546350.html

最后,解决办法就是加上这个函数即可:

virtual void InitPyThread() {
        PyEval_InitThreads();
}

然后运行就正常了。

文章的脚注信息由WordPress的wp-posturl插件自动生成



|2|left
打赏

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: