我使用AfxBeginThread
生成一个线程,这只是一个无限循环:
UINT CMyClass::ThreadProc( LPVOID param )
{
while (TRUE)
{
// do stuff
}
return 1;
}
如何在类析构函数中删除此线程?
我认为像
UINT CMyClass::ThreadProc( LPVOID param )
{
while (m_bKillThread)
{
// do stuff
}
return 1;
}
然后在析构函数中将m_bKillThread
设置为FALSE
。但是我仍然需要在析构函数中等待,直到线程死掉。
答案 0 :(得分:19)
主动杀死该主题:
使用AfxBeginThread
(CWinThread*
)的返回值来获取线程句柄(m_hThread
),然后将该句柄传递给TerminateThread Win32 API。这不是一种终止线程的安全方法,所以请继续阅读。
等待线程完成:
使用AfxBeginThread
(CWinThread*
)的返回值来获取成员m_hThread,然后使用WaitForSingleObject(p->m_hThread, INFINITE);
如果此函数返回WAIT_OBJECT_0
,则线程结束。而不是INFINITE
,您还可以在超时发生之前等待毫秒数。在这种情况下,将返回WAIT_TIMEOUT
。
向您的帖子发信号通知它应该结束:
在执行WaitForSingleObject
之前,只需设置线程应该退出的某种标志。然后在线程的主循环中,您将检查该bool值并打破无限循环。在析构函数中,您将设置此标志,然后执行WaitForSingleObject
。
更好的方法:
如果您需要更多控制权,可以使用boost conditions之类的内容。
答案 1 :(得分:5)
BTW,关于TerminateThread(),请这样使用。
DWORD exit_code= NULL;
if (thread != NULL)
{
GetExitCodeThread(thread->m_hThread, &exit_code);
if(exit_code == STILL_ACTIVE)
{
::TerminateThread(thread->m_hThread, 0);
CloseHandle(thread->m_hThread);
}
thread->m_hThread = NULL;
thread = NULL;
}
答案 2 :(得分:1)
你必须等待,直到线程做完所有事情。
if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0)
;//all right
else
;//report error
注意使用TerminateThread功能,这非常危险。
答案 3 :(得分:1)
首先,您必须以某种方式启动线程,以便MFC在finished时不删除该线程对象,MFC线程的默认设置是删除自己,因此您想要把它关掉。
m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED);
m_thread->m_bAutoDelete = FALSE;
m_thread->ResumeThread();
现在在线程中,您需要一种机制,调用者线程可以向其发送信号以结束自身。有多种方法,一种是WaitForSingleObject
来检查信号的状态,另一种方法是简单地向该线程发送消息以结束自身。这是优雅的结局而非杀死它。
当这个线程结束时(=退出线程函数,清理),你可以让主线程在它退出之前等待它完成。
int wait = 2000 // seconds ( I am waiting for 2 seconds for worker to finish)
int dwRes = WaitForSingleObject( m_thread->m_hThread, wait);
switch (dwRes)
{
case WAIT_OBJECT_0:
TRACE( _T("worker thread just finished") ); break;
case WAIT_TIMEOUT:
TRACE( _T("timed out, worker thread is still busy") ); break;
}
注意上面设置m_bAutoDelete = FALSE
使我们在线程完成时仍然有一个有效的句柄,所以我们可以等待它。你现在要做的最后一件事是删除CWinThread对象以释放它的内存(因为我们负责这样做)。