如何在工作线程中使用关闭的句柄 [英] How to use closed handle in a worker thread
问题描述
我使用Windows中的线程来将使用c ++制作的插件连接到python脚本。线程在会话期间被调用多次
问题:
如果我通过 ArgList
在 _beginthread
错误未处理的异常0x1E114A68(python27。 dll)in xxx.exe:0xC0000005:访问冲突读取位置0xFFFFFFFE。提出,我认为这是因为我在 CreatingThreads Windows开发人员中心:
p>
我是关于这个错误的起源吗?
我打电话给你
作为 ArgList
的 _ $ c> _beginthread
,并定义 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;
//通知解释器有关Python运行时库的路径
Py_SetProgramName(argv [0]);
//初始化Python解释器
Py_Initialize();
//初始化线程支持
PyEval_InitThreads();
//保存指向PyThreadState对象的指针
mainThreadState = PyThreadState_Get();
//获取对PyInterpreterState的引用
mainInterpreterState = mainThreadState-> interp;
//为此线程创建线程状态对象
myThreadState = PyThreadState_New(mainInterpreterState);
//释放全局锁
PyEval_ReleaseLock();
//获取全局锁
PyEval_AcquireLock();
//交换我的线程状态
tempState = PyThreadState_Swap(myThreadState);
//构建名称对象
pName = PyString_FromString(argv [1]);
//加载模块对象
pModule = PyImport_Import(pName);
// pDict是一个借用的引用
pDict = PyModule_GetDict(pModule);
// pFunc也是借用的引用
pFunc = PyDict_GetItemString(pDict,argv [2]);
//做Python的事情
PyObject * pArgs2,* pValue2;
pArgs2 = Py_BuildValue((s),argv [3]);
pValue2 = PyObject_CallObject(pFunc,pArgs2);
textfile3<<<< PyInt_AsLong(pValue2)<< endl<
textfile3.close();
//清理
Py_DECREF(pModule);
Py_DECREF(pName);
//换出当前线程
PyThreadState_Swap(tempState);
//释放全局锁
PyEval_ReleaseLock();
//清除线程状态
PyThreadState_Clear(myThreadState);
PyThreadState_Delete(myThreadState);
//完成Python解释器
Py_Finalize();
_endthread();
};
我从主线程调用它(在工作线程完成之前关闭) :
handle =(HANDLE)_beginthread(py_embed,0,NULL);
注意:与此相关的问题1是在这里
解决方案所以,我终于找到了问题。希望这可以帮助任何人有相同的问题我做了
我还是不完全明白这是如何工作,但我基本上需要动态分配内存在堆使用<$ c中的c $ c> new (和c中的
malloc
)。有关此此处的更多信息
在我的例子中,我需要这样做:
#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{cmd-> argv [i] = argv [i];}
handle =(HANDLE) _beginthread(py_embed,0,(void *)cmd);
我还需要更好地理解这一点,还学习如何解决分配< $ c> delete 但我的方式正确。
注意:我仍然需要帮助Question1 与此相关,因此请查看一下。
I'm using threads in Windows to connect a plug-in made in c++ to a python script. The thread is to be called many times in the duration of the session
Question:
If I pass the
ArgList
in the_beginthread
the error "Unhandled exception at 0x1E114A68 (python27.dll) in xxx.exe: 0xC0000005: Access violation reading location 0xFFFFFFFE." is raised and I think it's because of this i read in CreatingThreads of Windows Dev Center:" Note that if you were to close the handle to a worker thread before it terminated, this does not terminate the worker thread. However, the handle will be unavailable for use in subsequent function calls."
Am I right about the origin of this error? How do I work past this?
Code:
I called
_beginthread
withNULL
as theArgList
and defined theArgList
inside the worker thread just for getting the thread to work. Here's the code for the worker thread:Note: I noticed while debugging that
_endthread()
is not reached. Is that normal?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(); };
And what I do to call it from the main thread(that closes before the worker thread is finished):
handle=(HANDLE) _beginthread(py_embed,0,NULL);
NOTE:Question 1 related to this is here
解决方案So, i finally found the problem. Hope this helps anyone who has the same problem i did
I still don't fully understand how this works but i basically need to dynamically allocate memory on the heap using
new
in c++ (andmalloc
in c). More information about this hereIn my case I will need to do something like this:
#define NUM_ARGUMENTS 4 typedef struct{ int argc; char *argv[NUM_ARGUMENTS]; }SENDTOPY;
And then on the main thread:
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);
I still need to understand this better, and also learn how to deallocate at the end with
delete
but I'm in the right way.Note: I still need help on the Question1 related to this, so please have a look at it.
这篇关于如何在工作线程中使用关闭的句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!