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

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

内容简介: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

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

查看所有标签

猜你喜欢:

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

软件的奥秘

软件的奥秘

[美] V. Anton Spraul / 解福祥 / 人们邮电出版社 / 2017-9-1 / 49

软件已经成为人们日常生活与工作中常见的辅助工具,但是对于软件的工作原理,很多人却不是非常了解。 本书对软件的工作原理进行了解析,让读者对常用软件的工作原理有一个大致的了解。内容涉及数据如何加密、密码如何使用和保护、如何创建计算机图像、如何压缩和存储视频、如何搜索数据、程序如何解决同样的问题而不会引发冲突以及如何找出最佳路径等方面。 本书适合从事软件开发工作的专业技术人员,以及对软件工作......一起来看看 《软件的奥秘》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具