【引用】如何结束线程运行(转)

举报
清雨小竹 发表于 2022/09/25 01:13:14 2022/09/25
【摘要】 在一些应用程序中,除非用户去结束应用程序的运行,否则其中的子线程会一直处于运行状态。如果应用程序在结束时不主动通知子线程退出,有可能导致主线程结束后,子线程的系统资源得不到释放。如何通知子线程结束运行呢?这需要在程序设计阶段就考虑到,通常可以用事件、消息或全局变量来通知子线程退出运行循环或消息循环。消息通知方式适合用来通知有消息循环...
在一些应用程序中,除非用户去结束应用程序的运行,否则其中的子线程会一直处于运行状态。如果应用程序在结束时不主动通知子线程退出,有可能导致主线程结束后,子线程的系统资源得不到释放。如何通知子线程结束运行呢?这需要在程序设计阶段就考虑到,通常可以用事件、消息或全局变量来通知子线程退出运行循环或消息循环。消息通知方式适合用来通知有消息循环的用户界面线程退出,但理论上讲消息机制是不可靠的(消息可能会丢失,尽管可能性很小);事件通知的方式及时并且可靠,在应用程序准备结束运行前,设置一个通知事件;子线程的运行循环中不断检查通知事件,一旦发现事件信号设置,就可以退出循环,从而结束子线程的运行。主线程在设置通知事件后,不能马上退出,而应该等待子线程先结束后再退出。等待子线程结束方法很多,例如使用循环(while或 WM_CLOSE消息循环)检测线程状态等待,WaitForSingleObject函数等待,还有Sleep函数等待等,但有些方法在使用时可能导致线程死锁,因而必须小心。
举例来说,一个子线程不断将自己的处理进度刷新到对话框的进度条控件,这里刷新对话框事实上有赖于主线程的消息循环来处理刷新消息;如果用户不等处理结束就点击关闭对话框按钮,而主线程设置通知事件后如果使用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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。