0
点赞
收藏
分享

微信扫一扫

python编程(多线程c回调python)

倪雅各 2022-11-23 阅读 144


    python下面的GIL决定了每次thread执行的时候不能实现完全的并发执行。所以如果多线程c调用python代码的时候,有很多地方需要注意一下。

1、开始处添加多线程支持

// threads launched after everything is ok
PyEval_InitThreads();

2、在子线程创建之前,主线程释放控制权

PyEval_ReleaseThread(PyThreadState_Get());

3、子线程创建之前必须完成其他所有操作

Py_Initialize();     
if (!Py_IsInitialized()) return -1;

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");

//import Module
pModule = PyImport_ImportModule("hello");
if (!pModule) {
printf("Can't import Module!/n");
return -1;
}

4、子线程调用python的时候先用锁保护好

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

PyObject* pFun = PyObject_GetAttrString(pModule, "show");
PyObject_CallFunction(pFun, "s", param_name);
Py_DECREF(pFun);
PyGILState_Release(gstate);

5、子线程结束后交还给主线程时,最好再次锁住虚拟机

PyGILState_Ensure(); 
Py_DECREF(pModule);

//Release
Py_Finalize();

6、完整流程如下所示,

#include <stdio.h>  
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <Python.h>

int g_exit = 0;
PyObject* pModule;

void sig_process(int sig)
{
g_exit = 1;
}

void func(void* param_name)
{
while(!g_exit){
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

PyObject* pFun = PyObject_GetAttrString(pModule, "show");
PyObject_CallFunction(pFun, "s", param_name);
Py_DECREF(pFun);
PyGILState_Release(gstate);
}
}

int main()
{
pthread_t pid1, pid2, pid3;

signal(SIGINT, sig_process);

Py_Initialize();
if (!Py_IsInitialized()) return -1;

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");

//import Module
pModule = PyImport_ImportModule("hello");
if (!pModule) {
printf("Can't import Module!/n");
return -1;
}

// threads launched after everything is ok
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);

PyGILState_Ensure();
Py_DECREF(pModule);

//Release
Py_Finalize();
return 0;

}

    其中编译方法为,

gcc process.c -I/usr/include/python2.7 -ldl -lutil -lpthread -lpython2.7 -o process

    而python脚本文件内容为,

def show(name):   
print 'hello ' + name


举报

相关推荐

0 条评论