300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > VC++ 中主线程等待子线程结束的方法

VC++ 中主线程等待子线程结束的方法

时间:2024-02-15 22:47:53

相关推荐

VC++ 中主线程等待子线程结束的方法

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()函数创建线程,原因如下:

Them_hThreaddatamemberisapublicvariableoftypeHANDLE.Itisonlyvalidifunderlyingthreadcurrentlyexists。

所以当线程结束之后,线程句柄不存在了,也就监听不到子线程终止了。

这里建议使用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

本文参考网址:

/fly0413/article/details/82464193

在此对原作者表示感谢。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。