python程式設計(多執行緒c回撥python)
阿新 • • 發佈:2019-02-07
【 宣告:版權所有,歡迎轉載,請勿用於商業用途。 聯絡信箱: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