python c语言 多线程,C单线程和多线程处理Python,c,及,python

本文介绍了如何在C语言中调用Python函数,并在多线程环境中进行处理。强调了Python环境初始化只需一次,最后销毁一次的重要性,避免反复创建和摧毁Py模块导致异常错误。同时,展示了主线程初始化和退出的代码,以及线程内调用Python函数的详细步骤,包括GIL(全局解释器锁)的使用,确保线程安全。
摘要由CSDN通过智能技术生成

1. c单线程处理python

……

#include

……

/*

其他初始化处理

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)

{

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

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

……

/* 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)

{

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

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值