如何在工作线程中使用闭合句柄

时间:2014-03-14 19:38:09

标签: python c++ multithreading

我在Windows中使用线程将c ++编写的插件连接到python脚本。在会话期间多次调用该线程

问题:

如果我通过ArgList中的_beginthread错误" xxx.exe中的0x1E114A68(python27.dll)处的未处理异常:0xC0000005:访问冲突读取位置0xFFFFFFFE。 " 被提出,我认为是因为我在Windows开发人员中心的CreatingThreads中读到了这个内容:

"请注意,如果您在终止之前关闭工作线程的句柄,则不会终止工作线程。但是,句柄将无法用于后续函数调用。"

我对这个错误的起源是否正确?我如何解决这个问题?

代码:

我使用_beginthread作为NULL调用了ArgList,并在工作线程中定义了ArgList,只是为了让线程正常工作。这是工作线程的代码:

注意:我注意到调试时未达到_endthread()。这是正常的吗?

void py_embed (void*data){

char *argv[4]={"PythonPlugIn2","bridge","test_callsign","MAH543"};
int argc=4;

ofstream textfile3;
textfile3.open("FP_python_embed.txt");

PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
PyThreadState *mainThreadState,*myThreadState,*tempState;
PyInterpreterState *mainInterpreterState;

//To inform the interpreter about paths to Python run-time libraries
Py_SetProgramName(argv[0]);

// Initialize the Python Interpreter
Py_Initialize();

// Initialize thread support
PyEval_InitThreads();

// Save a pointer to the main PyThreadState object
mainThreadState = PyThreadState_Get();

// Get a reference to the PyInterpreterState
mainInterpreterState = mainThreadState->interp;

// Create a thread state object for this thread
myThreadState = PyThreadState_New(mainInterpreterState);

// Release global lock
PyEval_ReleaseLock();

// Acquire global lock
PyEval_AcquireLock();

// Swap in my thread state
tempState = PyThreadState_Swap(myThreadState);

// Build the name object
pName = PyString_FromString(argv[1]);

// Load the module object
pModule = PyImport_Import(pName);

// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);

// pFunc is also a borrowed reference 
pFunc = PyDict_GetItemString(pDict, argv[2]);

//Do the Python things
PyObject *pArgs2, *pValue2;
pArgs2=Py_BuildValue("(s)",argv[3]);
pValue2 = PyObject_CallObject(pFunc, pArgs2);
textfile3<<PyInt_AsLong(pValue2)<<endl<<" worked1";
textfile3.close();

// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);

// Swap out the current thread
PyThreadState_Swap(tempState);

// Release global lock
PyEval_ReleaseLock();

// Clean up thread state
PyThreadState_Clear(myThreadState);
PyThreadState_Delete(myThreadState);

// Finish the Python Interpreter
Py_Finalize();

_endthread();
};

我从主线程中调用它(在工作线程完成之前关闭):

handle=(HANDLE) _beginthread(py_embed,0,NULL);

注意:与此相关的问题1为here

1 个答案:

答案 0 :(得分:1)

所以,我终于找到了问题。希望这可以帮助那些遇到同样问题的人

我仍然不完全理解这是如何工作的,但我基本上需要使用c ++中的new(以及c中的malloc)在堆上动态分配内存。有关此here

的详细信息

在我的情况下,我需要做这样的事情:

#define NUM_ARGUMENTS 4
typedef struct{
int argc;
char *argv[NUM_ARGUMENTS];
}SENDTOPY;

然后在主线上:

SENDTOPY *cmd;

char *argv[4]={"PythonPlugIn2","bridge","test_callsign","MAH543"};
int i;

cmd= new SENDTOPY();
cmd->argc=4;
for( i = 0; i < NUM_ARGUMENTS; i++ )
{cmd->argv[i] = argv[i];}

handle=(HANDLE) _beginthread(py_embed,0,(void*)cmd);

我仍然需要更好地理解这一点,并且还要学习如何在delete结束时解除分配,但我的方法正确。

注意:我仍然需要与Question1相关的帮助,所以请看一下。