如何在工作线程中使用关闭的句柄 [英] How to use closed handle in a worker thread

查看:186
本文介绍了如何在工作线程中使用关闭的句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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 with NULL as the ArgList and defined the ArgList 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++ (and malloc in c). More information about this here

In 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆