c单线程及多线程处理python
1. c单线程处理python
……
#include <python3.7m/Python.h>
……
/*
其他初始化处理
pcRespJson 接收python函数返回值 如果有的话
*/
const char *pcRespJson = NULL;
/* python 对象初始化 */
PyObject *pstName = NULL;
PyObject *pstModule = NULL;
PyObject *pstFunc = NULL;
PyObject *pstArgvs = NULL;
PyObject *pstRetValue = NULL;
/* python 初始化 */
Py_Initialize(); //初始化Python环境
if ( !Py_IsInitialized() ) //检测是否初始化成功
{
printf("\r\nPy_IsInitialized() failed \r\n");
return 1;
}
/* 下面处理 python */
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
/* python 文件名称 print_hello.py */
pstName = PyUnicode_FromString("print_hello");
pstModule = PyImport_Import(pstName);
Py_DECREF(pstName);
if(pstModule != NULL)
{
/* print_hello.py 中的函数名称 myPrint */
pstFunc = PyObject_GetAttrString(pstModule, "myPrint");
if((pstFunc == NULL) || (PyCallable_Check(pstFunc) == BOOL_FALSE))
{
Py_DECREF(pstModule);
return ERROR_FAILED;
}
/* 函数 myPrint 需要几个参数,可以多个*/
pstArgvs = PyTuple_New(2);
PyTuple_SetItem(pstArgvs, 0, Py_BuildValue("s", “name”));
PyTuple_SetItem(pstArgvs, 1, Py_BuildValue("s", "time"));
/* 调用 myPrint 函数处理 */
pstRetValue = PyObject_CallObject(pstFunc, pstArgvs);
Py_DECREF(pstArgvs);
if(pstRetValue == NULL)
{
Py_DECREF(pstFunc);
Py_DECREF(pstModule);
return ERROR_FAILED;
}
/* myPrint 函数返回值转码处理 */
pcRespJson = PyUnicode_AsUTF8(pstRetValue);
if(pcRespJson == NULL)
{
/* 如果python 有 json 返回值*/
pcRespJson = PyBytes_AsString(pstRetValue);
}
if(pcRespJson != NULL)
{
/*
处理返回 json 串 pcRespJson
……
……
*/
}
Py_DECREF(pstRetValue);
Py_DECREF(pstFunc);
Py_DECREF(pstModule);
}
/* python 去初始化 */
Py_Finalize();
2. c多线程处理 python 踩坑教训
-
在项目中一定是只初始化一次,最后摧毁一次
建议不要反复创建摧毁Py模块
否则,会出现一些异常错误还有段错误。 -
编译的时候带上: -lpython3.7m
-
https://bbs.csdn.net/topics/390824020
Py_Initialize(); // //谁初始化谁释放原则,实际使用中需要存一个值判定是否是自己初始化的
Py_Finalize();//摧毁好像会不完全摧毁,导致许多奇怪问题多线程使用我不清楚,但是我在项目中一定是只初始化一次,最后摧毁一次
建议LZ不要反复创建摧毁Py模块
2.1 主线程 初始化代码
void Thread_Init()
{
int iRet = 0;
Py_Initialize(); //初始化Python环境
if ( !Py_IsInitialized() ) //检测是否初始化成功
{
printf("\r\nPy_IsInitialized() failed \r\n");
return 1;
}
else
{
PyEval_InitThreads(); //开启多线程支持
PyEval_ReleaseThread(PyThreadState_Get());
}
}
2.2 主线程 去初始化代码
void Thread_Exit()
{
PyGILState_Ensure() ;
Py_Finalize();
return ;
}
2.3 c多线程python处理:
……
#include <python3.7m/Python.h>
……
/* pcRespJson 接收python函数返回值 */
const char *pcRespJson = NULL;
/* python 对象初始化 */
PyObject *pstName = NULL;
PyObject *pstModule = NULL;
PyObject *pstFunc = NULL;
PyObject *pstArgvs = NULL;
PyObject *pstRetValue = NULL;
/* 线程python 初始化 */
PyGILState_STATE gstate;
gstate = PyGILState_Ensure(); //如果没有GIL,则申请获取GIL
Py_BEGIN_ALLOW_THREADS;
Py_BLOCK_THREADS;
/* 下面处理 python */
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
/* python 文件名称 print_hello.py */
pstName = PyUnicode_FromString("print_hello");
pstModule = PyImport_Import(pstName);
Py_DECREF(pstName);
if(pstModule != NULL)
{
/* print_hello.py 中的函数名称 myPrint */
pstFunc = PyObject_GetAttrString(pstModule, "myPrint");
if((pstFunc == NULL) || (PyCallable_Check(pstFunc) == BOOL_FALSE))
{
Py_DECREF(pstModule);
return ERROR_FAILED; /* ERROR_FAILED 这是个返回值的宏 1 */
}
/* 函数 myPrint 需要几个参数,可以多个*/
pstArgvs = PyTuple_New(2);
PyTuple_SetItem(pstArgvs, 0, Py_BuildValue("s", “name”));
PyTuple_SetItem(pstArgvs, 1, Py_BuildValue("s", "time"));
/* 调用 myPrint 函数处理 */
pstRetValue = PyObject_CallObject(pstFunc, pstArgvs);
Py_DECREF(pstArgvs);
if(pstRetValue == NULL)
{
Py_DECREF(pstFunc);
Py_DECREF(pstModule);
return ERROR_FAILED;
}
/* myPrint 函数返回值转码处理 */
pcRespJson = PyUnicode_AsUTF8(pstRetValue);
if(pcRespJson == NULL)
{
/* 如果python 有 json 返回值*/
pcRespJson = PyBytes_AsString(pstRetValue);
}
if(pcRespJson != NULL)
{
/*
处理返回 json 串 pcRespJson
……
……
*/
}
Py_DECREF(pstRetValue);
Py_DECREF(pstFunc);
Py_DECREF(pstModule);
}
/* 线程python 去初始化 */
Py_UNBLOCK_THREADS;
Py_END_ALLOW_THREADS;
PyGILState_Release(gstate); //释放当前线程的GIL
2.4 多线程python处理异常处理-踩坑
某个线程1加锁处理任务时出错了需要及时释放锁,否则另外一个线程会卡死在取锁的地方或者其他python处理的地方。
现象:代码会卡在不同的地方
有的是调用python 前后几行,或者python脚本里面不同的地方。
//异常情况处理释放当前线程锁GIL
if (!nHold)
{
PyGILState_Release(gstate); //释放当前线程的GIL
}
参考:
https://www.csdn.net/gather_23/NtTaAg4sMzItYmxvZwO0O0OO0O0O.html