问题描述:c程序中需要多次调用python脚步;
两个和全局锁有关的宏,Py_BEGIN_ALLOW_THREADS 和 Py_END_ALLOW_THREADS。这两个宏是为了在较长时间的C函数调用前,临时释放全局锁,完成后重新获取全局锁,以避免阻塞其他python的线程继续运行。这两个宏的用法如下:
初始做法:每次调用python脚本时,开始初始化python环境(Py_Initialize),调用完之后结束python环境(Py_Finalize();)
问题:程序偶然会出现崩溃的现象;
c程序多次调用python脚本的正确打开模式如下:
1. 在主线程中这样处理
// 初始化
Py_Initialize();
if ( !Py_IsInitialized() )
return
// 初始化线程支持
PyEval_InitThreads();
// 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。
PyEval_ReleaseThread(PyThreadState_Get());
// 其他的处理,如启动子线程等
......
// 保证子线程调用都结束后
PyGILState_Ensure();
Py_Finalize();
// 之后不能再调用任何python的API
2. 在主线程,或者子线程中,调用python本身函数采用如下处理
PyGILState_STATE state;
state = PyGILState_Ensure();
...
// 调用python的API函数处理
...
PyGILState_Release(state);
注:
两个和全局锁有关的宏,Py_BEGIN_ALLOW_THREADS 和 Py_END_ALLOW_THREADS。这两个宏是为了在较长时间的C函数调用前,临时释放全局锁,完成后重新获取全局锁,以避免阻塞其他python的线程继续运行。这两个宏的用法如下:
PyGILState_STATE state;
state = PyGILState_Ensure();
// 调用python的API函数处理
......
Py_BEGIN_ALLOW_THREADS
// 调用需要长时间的C函数
......
Py_END_ALLOW_THREADS
// 调用python的API函数处理
......
PyGILState_Release(state);
参考资料:
http://blog.csdn.net/liguangyi/article/details/1659697
http://blog.csdn.net/cedricporter/article/details/6810665
http://www.cppblog.com/API/archive/2013/12/06/204618.aspx