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 踩坑教训

  1. 在项目中一定是只初始化一次,最后摧毁一次
    建议不要反复创建摧毁Py模块
    否则,会出现一些异常错误还有段错误。
  2. 编译的时候带上: -lpython3.7m

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

参考:

https://www.csdn.net/gather_23/NtTaAg4sMzItYmxvZwO0O0OO0O0O.html

猜你喜欢

转载自blog.csdn.net/lqy971966/article/details/108431602