void WaitForThreadExit(void)
{DWORD dwRet;        //返回值MSG msg;            int wait_count=4;    //线程句柄有4个int nExitThreadCount=0;    //记录线程退出个数while(1){dwRet = MsgWaitForMultipleObjects(wait_count, hArray, FALSE, INFINITE, QS_ALLINPUT);    //等待时间和消息,不阻塞消息if (dwRet == WAIT_OBJECT_0 + wait_count){//消息到达队列,需要对消息进行重判断防止意外退出或卡死while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))//获取队列消息 PM_REMOVE -PeekMessage处理后,消息从队列里除掉。{if (msg.message==WM_QUIT||msg.message==WM_CLOSE)  {break;}TranslateMessage(&msg);    //将虚拟键消息转换为字符消息DispatchMessage(&msg);    //发一个消息给窗口程序}}else if (dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0+ wait_count){//线程组中返回消息nExitThreadCount++;if (nExitThreadCount < 4){//将等待数组句柄移位,使得连续句柄之间没有null。TRACE("一个线程退出了\n");int nIndex=dwRet-WAIT_OBJECT_0;hArray[nIndex]=hArray[wait_count-1];hArray[wait_count-1]=NULL;wait_count--;}else{TRACE("4个线程都退出了\n");break;}}else{//错误退出DWORD dErrCode=GetLastError();break;}}
}

为什么不用WaitForSingleObject()来监听事件完成
因为使用之后,会阻塞消息传递。使用MsgWaitForMultipleObjects既可以监听事件又可以监听消息。

这里创建线程时,建议不要使用AfxBeginThread()函数创建线程,原因如下:
The m_hThread data member is a public variable of type HANDLE. It is only valid if underlying thread currently exists。
所以当线程结束之后,线程句柄不存在了,也就监听不到子线程终止了。
这里建议使用CreateThread()创建线程。具体使用方法

MsgWaitForMultipleObjects()多接收一个参数,允许指定哪些消息是观察对象

DWORD MsgWaitForMultipleObjects(DWORD nCount,          // 表示pHandles所指的handles数组的元素个数,最大容量是MAXIMUM_WAIT_OBJECTS LPHANDLE pHandles,     // 指向一个由对象handles组成的数组,这些handles的类型不需要相同BOOL fWaitAll,         // 是否等待所有的handles被激发才返回DWORD dwMilliseconds,  // 超时时间DWORD dwWakeMask       // 欲观察的用户输入消息类型
);

返回值
WAIT_TIMEOUT :因时间终了而返回
WAIT_OBJECT_0 :当bWaitAll是TRUE
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) :当bWaitAll是FALSE,将返回值减去WAIT_OBJECT_0,就表示数组中哪一个handle被激发了
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1) :等待的对象中有任何mutexes,且在结束前没有释放mutex,会导致此错误
WAIT_FAILED :函数失败时返回该值,可以使用GetLastError()找出失败的原因
WAIT_OBJECT_0 + nCount :消息到达队列

MsgWaitForMultipleObjects()的正确使用方式是改写主消息循环,使得激发状态的handles得以像消息一样被对待。通常程序中只会有一个地方调用MsgWaitForMultipleObjects(),而这个调用存在于消息循环中

注意:
1. 在收到WM_QUIT之后,Windows仍然会传送消息给你,如果要在收到WM_QUIT之后等待所有线程结束,必须继续处理你的消息,否则窗口会变得反应迟钝,而且没有重绘能力。

2.MsgWaitForMultipleObjects()不允许handles数组中有缝隙产生。所以当某个handle被激发了时,应该在下一次调用MsgWaitForMultipleObjects之前,先把handles数组做个整理、紧压,不要只是把数组中的handle设为NULL

3.如果有另一个线程改变了对象数组,而那是你正在等待的,那么需要一种方法,可以强迫MsgWaitForMultipleObjects返回,并重新开始,以包含新的handle

本文参考网址:
https://blog.csdn.net/fly0413/article/details/82464193
在此对原作者表示感谢。

VC++ 中主线程等待子线程结束的方法相关推荐

  1. c++主线程等待子线程结束_简单明了的 Python 多线程来了 | 原力计划

    作者 | 万里羊责编 | 王晓曼出品 | CSDN博客线程和进程计算机的核心是CPU,它承担了所有的计算任务,就像是一座工厂在时刻运行.如果工厂的资源有限,一次只能供一个车间来使用,也就是说当一个车间 ...

  2. Java多线程之----主线程会等待子线程结束再结束么,怎么让主线程等待子线程结束呐?

    首先给出结论: 主线程和子线程之间没有谁先谁后结束这种关联,它们只是各自负责自己的线程任务,如果该线程的任务结束了,该线程自然会结束运行. talk is cheap,show me the code ...

  3. 【多线程】学习记录七种主线程等待子线程结束之后在执行的方法

    最近遇到一个问题需要主线程等待所有的子线程结束,才能开始执行,统计所有的子线程执行结果,返回,网上翻阅各种资料,最后记录一下,找到七种方案 第一种:while循环 对于"等待所有的子线程结束 ...

  4. 【Java并发编程】主线程等待子线程的多种方法

    文章目录 1.Thread sleep() 2.Thread join() 3.synchronized 等待唤醒机制 4.ExecutorService isTerminated() + while ...

  5. Java多线程协作CountDownLatch,主线程等待子线程结束

    CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count);构造方 ...

  6. java 主线程等待_Java实现主线程等待子线程

    本文介绍两种主线程等待子线程的实现方式,以5个子线程来说明: 1.使用Thread的join()方法,join()方法会阻塞主线程继续向下执行. 2.使用Java.util.concurrent中的C ...

  7. 如何实现java主线程等待子线程执行完毕之后再执行?

    本文转自:问题:如何实现java主线程等待子线程执行完毕之后再执行? - jseven - 博客园 点击关注强哥,查看更多精彩文章呀 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完 ...

  8. Java并发编程原理与实战六:主线程等待子线程解决方案

    Java并发编程原理与实战六:主线程等待子线程解决方案 参考文章: (1)Java并发编程原理与实战六:主线程等待子线程解决方案 (2)https://www.cnblogs.com/pony1223 ...

  9. Java主线程等待子线程、线程池

    public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...

最新文章

  1. 【jsp】写jsp文件的准备
  2. 地脚螺钉直径系列_百科:螺栓、螺钉、螺丝三个概念,别再傻傻分不清!
  3. javascript:12种JavaScript MVC框架之比较
  4. 第七:不要表现得消极,仅仅因为你所做的事情不是你的兴趣所在
  5. 【机器学习基础】(二):理解线性回归与梯度下降并做简单预测
  6. python莫比乌斯_莫比乌斯函数 - osc_7eqzxl4g的个人空间 - OSCHINA - 中文开源技术交流社区...
  7. 病毒(信息学奥赛一本通-T1396)
  8. 艾伟:彻底解决刷新重复提交问题,你还在用Response.Redirect吗?
  9. 一文搞定移动端适配!
  10. office 2016搜索联机模板是灰色的解决方案
  11. 税号输入框 将input框中的输入自动转化成半角大写
  12. windows下安装使用Nide
  13. sublime text3 字体样式_Sublime Text3 Github最受欢迎主题字体推荐!
  14. 【实战】如何抓住Facebook天秤币的机会
  15. 周虽旧邦,其命维新(学习日志)
  16. c#语言入门 刘老师,c#单元测试实例(学习刘老师视频)
  17. 加快发展职业教育 让每个人都有人生出彩机会
  18. 聚乙二醇表面修饰氧化锌量子点/FA-PEG-CdTe/CdS量子点荧光探针特异性标记Hep-2的制备
  19. 基于点击量的趋势分析python_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析详解...
  20. Linux以及银河麒麟系统的一些基本认识

热门文章

  1. 防火墙、路由器、交换机+模拟软件+流控
  2. 公众号 多服务器配置_微信公众号的服务器配置
  3. 联想服务器系统机房,联想10月1日完成收购IBM x86服务器
  4. 康定游记-宝宝征服4300米海拔折多山
  5. 事后诸葛亮-团队总结
  6. linux安装nodejs 7,在CentOS 7上安装Node.js的4种方法
  7. 如何免费下载qq音乐 ----ctf学习之php漏洞
  8. 大学计算机基础教程第10章数据通信技术基础
  9. 大学生计算机应用基础实验6,计算机应用基础实验6.doc
  10. 网站1周内自动登录功能实现