首先仔细阅读问题。
有一个工作线程从CTest类的CreateInstance中生成。这是班级的原型。 hThread是线程的句柄,hEventShutdown是用于在程序退出时关闭线程的事件。 WaitForShutdown是一个公共函数,用于发出信号hEventShutdown并等待句柄线程,直到线程正常退出。从应用程序的退出调用WaitForShutdown。
//pseudocode
CTest
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();
public:
HANDLE hThread;
HANDLE hEventShutdown;
}
void CTest::CTest* CreateInstance()
{
// spawn a thread, pass 'this' pointer to thread , use beginthreadex
hThread = beginthreadex ( threadproc, this );
}
unsigned int CTest::threadproc( void *pv)
{
Ctest *ptest = (Ctest*)pv;
do
{
HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle }
dwResult = Waitformultipleobjects( hArrary , 2);
if ( dwResult == WAIT_OBJECT_0)
delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)
if(dwResult == WAIT_OBJECT_0 + 1)
Doprocessing(); //DoProcessing when other thread signal someotherhandle
}while (1)
void CTest::WaitForShutdown()
{
SetEvent ( hEventShutdown);
WaitForSingleObject ( hThread,INFINITE);
}
void CTest::~CTest()
{
Closehandle(hThread)
Closehandle(hEventShutdown);
}
现在,如果你仔细查看代码,你会发现事件是从WaitForShutdown函数发出信号,线程来自WaitForMultipleOjbects并删除了CTest的指针。这意味着调用CTest的析构函数,这显然会关闭线程句柄(hThread)。但WaitForShutdown中的WaitForSingleObject实际上正在等待线程句柄。所以这里的行为将是不确定的(我想是的,如果我错了,你可以纠正我)。另一个问题是当WaitForSingleObject在其成员hThread上等待不正确时,调用Ctest的析构函数。我无法从线程中删除删除pTest,因为由于某些原因它必须在那里。
您如何建议上述解决方案?
我能想到的几个解决方案:
纠正我。
您的反馈表示赞赏。
答案 0 :(得分:2)
处理此问题的最简单方法是在WaitForSingleObject
返回后从WaitForShutdown中删除线程。这确保了您需要的所有句柄 - 更重要的是,对象本身 - 保持活力到最后。
答案 1 :(得分:1)
我按原样运行了这件作品。似乎它有效,并且它不会崩溃。
奇怪的是,在我们离开CloseHandle(hthread)
之前,我们可以致电WaitforSingleObject(hThread,INFINITE)
。
当然,加入线程的“学术”方式首先是WaitForSingleObject(hThread,INFINITE)
而不是CloseHandle(hThread)
。这就是我的建议 - 以这种方式做。
我不必再添加了。