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

栏目: Python · 发布时间: 8年前

内容简介:python编程(多线程c回调python)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beautiful Code

Beautiful Code

Greg Wilson、Andy Oram / O'Reilly Media / 2007-7-6 / GBP 35.99

In this unique work, leading computer scientists discuss how they found unusual, carefully designed solutions to difficult problems. This book lets the reader look over the shoulder of major coding an......一起来看看 《Beautiful Code》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具