1. 程式人生 > >python程式設計(多執行緒c回撥python)

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