我正在将python嵌入到我的c++中程序。我的程序将解析iput参数并调用relate python函数。当我运行我的程序时。我发现它的线程保持不变成长。每调用函数“embeddedpython”时,它会增加一个新线程,并且该线程不能被销毁。结果不是我所期望的。我的错在哪里?以下是我的代码:
#include<iostream>
#include<Python.h>
#include<pthread.h>
#include"tools.h"
#include"log.h"
#include"express.h"
int EmbededPython(const string &module, const string &func_name, const vector<Element *> &arg_elmts, string &output, string &errmsg);
int PythonCall(const string &module, const string &funcname, const string &input, string &output, string &errmsg)
{
vector<string>arg_vec;
vector<Element *>arg_elmts;
vector_guard<Element> elmts_guard(arg_elmts);
char * input_str = (char *)malloc(input.length()+1);
strcpy(input_str, input.c_str());
//split will modify the content of string
split(input_str, arg_vec, ",");
free(input_str);
for(unsigned int i = 0; i < arg_vec.size(); i++) {
trim(arg_vec[i]);
const char * pExpress = arg_vec[i].c_str();
ExpressCaculator Caculator(NULL);
Element *pElement = Caculator.ParseAndCaculate(pExpress);
if(!pElement) {
errmsg += "param["+string(pExpress)+"] parsing error";
return -1;
}
arg_elmts.push_back(pElement);
}
int ret = 0;
EmbededPython(module, funcname, arg_elmts, output, errmsg);
return ret;
}
int EmbededPython(const string &module, const string &func_name, const vector<Element *> &arg_elmts, string &output, string &errmsg)
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
PyObject *pType, *pErrData, *pErrMsg,*pTraceback;
int ret = 0;
/* Make sure we own the GIL */
PyGILState_STATE state = PyGILState_Ensure();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
pName = PyString_FromString(module.c_str());
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, func_name.c_str());
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(arg_elmts.size());
for (unsigned int i = 0; i < arg_elmts.size(); ++i) {
ParamType data_type = (ParamType)arg_elmts[i]->GetValueType();
char* data_value = arg_elmts[i]->GetData();
log_notice("arg[%d]type[%d]value[%s]", i, data_type, data_value);
if(data_type == PARAM_TYPE_INT) {
pValue = PyInt_FromLong(atol(data_value));
} else if(data_type == PARAM_TYPE_FLOAT){
pValue = PyFloat_FromDouble(atof(data_value));
} else {
pValue = PyString_FromString(data_value);
}
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pFunc);
Py_DECREF(pModule);
log_error("Cannot convert argument[%s]", data_value);
errmsg += "Cannot convert argument" + string(data_value);
ret = -1;
goto PY_FINAL;
}
// pValue reference stolen here:
PyTuple_SetItem(pArgs, i, pValue);
}
/* Make sure we own the GIL */
//PyGILState_STATE state = PyGILState_Ensure();
pValue = PyObject_CallObject(pFunc, pArgs);
//pValue = PyObject_CallObject(pFunc, NULL);
//PyGILState_Release(state);
Py_DECREF(pArgs);
if (pValue != NULL) {
//Py_DECREF(pValue);
PyObject *pDictObj;
PyObject *pStrObj = NULL;
//get its __dict__ and convert it to string if is class ,module or function
if(PyClass_Check(pValue)
|| PyModule_Check(pValue)
|| PyFunction_Check(pValue)) {
pStrObj = PyString_FromString("__dict__");
pDictObj = PyObject_GetAttr(pValue, pStrObj);
Py_DECREF(pStrObj);
pStrObj = NULL;
if(pDictObj != NULL) {
pStrObj = PyObject_Str(pDictObj);
Py_DECREF(pDictObj);
}
} else { // direct to convert it to string
pStrObj = PyObject_Str(pValue);
}
Py_XDECREF(pValue);
if(pStrObj != NULL) {
output.assign(PyString_AsString(pStrObj));
} else {
log_error("Cannot convert result to string");
if (PyErr_Occurred()) {
PyErr_Fetch(&pType, &pErrData, &pTraceback);
pErrMsg = NULL;
if(pErrData !=NULL && (pErrMsg = PyObject_Str(pErrData)) != NULL) {
errmsg += PyString_AsString(pErrMsg);
} else {
errmsg += "<unknown exception data>";
}
Py_XDECREF(pErrMsg);
Py_XDECREF(pType);
Py_XDECREF(pErrData);
Py_XDECREF(pTraceback);
PyErr_Clear();
}
ret = -1;
}
} else {
PyErr_Fetch(&pType, &pErrData, &pTraceback);
pErrMsg = NULL;
if(pErrData !=NULL && (pErrMsg = PyObject_Str(pErrData)) != NULL) {
errmsg += PyString_AsString(pErrMsg);
} else {
errmsg += "<unknown exception data>";
}
Py_XDECREF(pErrMsg);
Py_XDECREF(pType);
Py_XDECREF(pErrData);
Py_XDECREF(pTraceback);
PyErr_Clear();
log_error("Call funciton[%s] error",func_name.c_str());
ret = -1;
}
} else {
if (PyErr_Occurred()) {
PyErr_Fetch(&pType, &pErrData, &pTraceback);
pErrMsg = NULL;
if(pErrData !=NULL && (pErrMsg = PyObject_Str(pErrData)) != NULL) {
errmsg += PyString_AsString(pErrMsg);
} else {
errmsg += "<unknown exception data>";
}
Py_XDECREF(pErrMsg);
Py_XDECREF(pType);
Py_XDECREF(pErrData);
Py_XDECREF(pTraceback);
PyErr_Clear();
}
log_error("Cannot find function[%s]", func_name.c_str());
ret = -1;
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
} else {
PyErr_Fetch(&pType, &pErrData, &pTraceback);
pErrMsg = NULL;
if(pErrData !=NULL && (pErrMsg = PyObject_Str(pErrData)) != NULL) {
errmsg += PyString_AsString(pErrMsg);
} else {
errmsg += "<unknown exception data>";
}
Py_XDECREF(pErrMsg);
Py_XDECREF(pType);
Py_XDECREF(pErrData);
Py_XDECREF(pTraceback);
PyErr_Clear();
log_error("Failed to load module[%s]", module.c_str());
ret = -1;
}
PY_FINAL:
/* Restore previous GIL state and return */
PyGILState_Release(state);
return ret;
}
using namespace std;
#define THREAD_SIZE 2
#define RUNTIMES 100000
char* _argv[100] = {};
pthread_t tid[THREAD_SIZE];
void* PyCallQT4S(void *ptr)
{
string module("QT4SLIB");
string func_name("GetTGT");
string input("\"account\",\"passwd\"");
string output;
string errmsg;
for(unsigned int i = 0; i < RUNTIMES; i++) {
log_notice("run times: %d", i);
log_notice("input[%s]", input.c_str());
PythonCall(module, func_name, input, output, errmsg);
log_notice("PYTHON CALL return[%s]", output.c_str());
log_notice("PYTHON ERRMSG[%s]", errmsg.c_str());
errmsg = "";
output = "";
}
return NULL;
}
int main(int argc, char* argv[])
{
PyThreadState* pyState;
init_log(argv[0], "../log");
set_log_pid(false);
for(int i = 0; i < argc; i++)
_argv[i] = argv[i];
Py_Initialize();
if (!PyEval_ThreadsInitialized()) {
PyEval_InitThreads();
pyState = PyEval_SaveThread();
}
for(unsigned int i=0; i < THREAD_SIZE; i++) {
int stacksize = 1024*128;
pthread_attr_t threadAttr;
pthread_attr_init(&threadAttr);
pthread_attr_setstacksize(&threadAttr, stacksize);
pthread_create(tid+i, &threadAttr, PyCallQT4S, NULL);
}
for(unsigned int i=0; i < THREAD_SIZE; i++) {
pthread_join(tid[i], NULL);
}
cout <<"all thread finish!"<< endl;
if (PyEval_ThreadsInitialized()) {
PyEval_RestoreThread(pyState);
}
Py_Finalize();
return 0;
}
目前没有回答
相关问题 更多 >
编程相关推荐