今天封装一个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插件自动生成