C语⾔多线程调⽤python
在做⽬标检测过程中,使⽤C语⾔实现上层从摄像头取流并截取帧的过程,⽬标检测使⽤Facebook开发的detectron开源项⽬(python). 整个流程获取待检测数据—>检测—>返回结果,那么上层获取的数据需要传递给python处理,这个时候就需要使⽤C语⾔调⽤python的接⼝。
本⽰例代码,主要介绍了多线程中C调python的基本流程。详情请参见官⽅⽹站。
C代码: process.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <Python.h> //必须加载的头⽂件
int g_exit = 0;
//定义python对象
PyObject* pModule;
PyObject* pTest;
void sig_process(int sig)
{
g_exit = 1;
}
void func(void* param_name)
{
//⼦线程执⾏之前,加锁
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
while(!g_exit){
//通过全局python模块对象,获取该模块中的⽅法
PyObject* pFun = PyObject_GetAttrString(pModule, "show");
//pTest 是python⽅法的返回值,使⽤ PyArg_Parse 接⼝可以解析为C风格的字符//串或者其他格式的数据
pTest = PyObject_CallFunction(pFun, "s", param_name);
PyObject* pFun2 = PyObject_GetAttrString(pModule, "objTest");
//调⽤接⼝,有多种⽅式调⽤
//PyObject_CallFunctionObjArgs(pFun2, pTest);
PyObject_CallFunction(pFun2, "sO", "str_test", pTest);
编程先学c语言还是pythonchar *cstr;
PyArg_Parse(pTest, "s", &cstr);
printf(">>> parse result: <%s>\n\n", cstr);
}
//释放线程中的锁,释放python对象
//注意,⼦线程中有循环的时候,加锁,和释放放在循环之外执⾏,不建议在⼦线程中频繁的创建和释放锁。
//Py_DECREF(pFun);
Py_DECREF(pFun2);
PyGILState_Release(gstate);
}
int main()
{
pthread_t pid1, pid2, pid3;
signal(SIGINT, sig_process);
//调⽤python之前必须初始化,以获取python解释器
Py_Initialize();
if (!Py_IsInitialized()) return -1;
//导⼊当前路径,或者是需要调⽤的python脚本路径
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyRun_SimpleString("sys.path.append('./')");
//这⾥物品将要调⽤的python脚本是hello.py, 将C字符串转为python对象
PyObject *pName;
pName = PyString_FromString("hello");
//导⼊要调⽤的python模块
pModule = PyImport_Import(pName);
if ( !pModule ) {
getchar();
return -1;
}
// 启动多线程之前,所有准备⼯作完成,这时候启⽤线程⽀持接⼝
//释放全局锁,作⽤是,使⼦线程可以获取解释器
//之后就可以执⾏线程了
PyEval_InitThreads();
PyEval_ReleaseThread(PyThreadState_Get());
/*if(pthread_create(&pid1, NULL, (void *(*)(void *))func, "output")) {
return -1; } */
if(pthread_create(&pid2, NULL, (void *(*)(void *))func, "show")){
return -1; }
/*if(pthread_create(&pid3, NULL, (void *(*)(void *))func, "see")){
return -1; } */
while(!g_exit){
sleep(3);
}
pthread_join(pid3, NULL);
pthread_join(pid2, NULL);
pthread_join(pid1, NULL);
//所有线程执⾏完成之后,释放所有python对象
PyGILState_Ensure();
Py_DECREF(pModule);
//Release
Py_Finalize();
return0;
}
python代码:hello.py
def show(name):
#print 'hello ' + name
#dict = {'obj':'show',}
#print(dict)
name = 'heshuqiang'
f_pos = 12.25365
f_sim = 0.9856
dict = "1, 'persion', 1.5, 1.6"
#print(str(fpos))
dict = name + ',' + str(f_pos) + ',' + str(f_sim) + ';'
print(dict)
return str(dict)
def objTest(str, para):
print('-------------------------------------')
print(para)
print('-------------------------------------')
print('--obj test')
print(str)
编译:
//gcc process.c -I/usr/include/python2.7 -L/usr/lib/python2.7 -lpthread -lpython2.7 -o process //具体根据⾃⼰安装python的环境确定库路径
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论