【引用】如何结束线程运行(转)
举例来说,一个子线程不断将自己的处理进度刷新到对话框的进度条控件,这里刷新对话框事实上有赖于主线程的消息循环来处理刷新消息;如果用户不等处理结束就点击关闭对话框按钮,而主线程设置通知事件后如果使用WaitForSingleObject函数等待子线程结束的话,极可能导致线程死锁。因为 WaitForSingleObject函数会将主线程挂起(任何消息都得不到处理)直到子线程结束事件发生;而子线程可能正在设置进度条,一直在等待主线程将刷新消息处理完毕返回才会检测通知事件。于是,死锁发生了,应用程序"死"在那里无法自动结束,必须靠任务管理器将其强制结束(可能造成该程序的资源和内存得不到释放)。
采用循环检测的方法比较安全些,但while循环本身可能会导致主线程乃至子线程阻塞,子线程也因得不到及时调度而迟迟难以结束,应用程序界面可能半天都没有响应。当子程序结束需要较长时间时,这是很令人厌恶的。不过,可以通过在while循环中加入Sleep(10~50)主动释放CPU占用来促使子线程得到调度,也可以通过调高子线程的优先级来促使其尽快结束。而通过在WM_CLOSE消息处理函数中检测子线程状态的方法最值得推荐,该方法既不会挂起主线程,也不会阻塞子线程。检测如果发现子线程仍然在活动状态,就再此向主窗口发送一个WM_CLOSE消息,以便再次进入该消息处理函数检查子线程状态,直到子线程结束为止。
下面是等待线程结束的示例代码:
void CProgressDlg::OnClose()
{
DWORD dwStatus;
if (m_pWorkerThread != NULL)
{
VERIFY(::GetExitCodeThread(m_pWorkerThread ->m_hThread, &dwStatus));
if (dwStatus == STILL_ACTIVE)
{
::SetEvent(g_hEventKill); // 通知子线程结束运行
// 调高子线程优先级
m_pWorkerThread->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
PostMessage(WM_CLOSE); // 给本窗口再发一个结束消息
Return;
}
else
{
delete m_pWorkerThread;
m_pWorkerThread = NULL;
}
}
CDialog::OnClose();
}
CDialog::OnClose();
}
文章来源: zzzili.blog.csdn.net,作者:清雨小竹,版权归原作者所有,如需转载,请联系作者。
原文链接:zzzili.blog.csdn.net/article/details/8265370
- 点赞
- 收藏
- 关注作者
评论(0)