本文共 2543 字,大约阅读时间需要 8 分钟。
在阻塞状态下仍能响应消息,支持多个对象等待激发
适用于多线程环境下,确保消息处理的及时性
MsgWaitForMultipleObjects()函数的作用是允许在阻塞状态下响应消息。这意味着当与之相关的对象被激发或消息到达队列时,函数会被唤醒并返回。
2.2 函数参数说明
DWORD MsgWaitForMultipleObjects( DWORD nCount, // handles数组的元素个数 LPHANDLE pHandles, // 指向handles数组 BOOL fWaitAll, // 是否等待所有handles DWORD dwMilliseconds, // 超时时间 DWORD dwWakeMask // 观察的消息类型掩码 );
- nCount:表示pHandles数组的元素个数,最大值为MAXIMUM_WAIT_OBJECTS
- pHandles:指向一个由多个对象句柄组成的数组,句柄类型不限
- fWaitAll:布尔标志,设为TRUE时等待所有handles返回
- dwMilliseconds:指定等待的超时时间
- dwWakeMask:指定需要观察的用户消息类型掩码
2.3 函数返回值
- WAIT_TIMEOUT:因超时返回
- WAIT_OBJECT_0:当fWaitAll为TRUE时,表示所有handles都已被激发
- 若fWaitAll为FALSE,返回值为WAIT_OBJECT_0到WAIT_OBJECT_0 + nCount -1,表示具体哪个handle被激发
- WAIT_ABANDONED_0到WAIT_ABANDONED_0 + nCount -1:表示有任何mutex被放弃
- WAIT_FAILED:函数执行失败时返回
- WAIT_OBJECT_0 + nCount:消息到达队列时返回
2.4 使用注意事项
- MsgWaitForMultipleObjects()应在主消息循环中使用
- 通常只在一个地方调用该函数
- 在处理WM_QUIT消息后,仍需继续处理消息以避免程序不响应
- handles数组必须保持连续且无空隙,避免使用NULL处理
- 多线程环境下需确保对handles数组的修改能够及时反映
void WaitForThreadExit(void){ DWORD dwRet; MSG msg; int wait_count = 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)) { 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) { 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;} }}
该示例用于等待多个线程退出,通过MsgWaitForMultipleObjects()函数实现非阻塞消息处理。
在消息队列中,除了处理退出消息外,还需处理其他类型消息以避免程序卡死。
MsgWaitForMultipleObjects()函数为开发者提供了在多线程环境下处理消息和对象激发的强大能力。通过合理配置参数和正确处理返回值,可以有效避免死锁和性能问题。
在实际开发中,选择合适的线程API对性能和资源占用有重要影响。Windows的MsgWaitForMultipleObjects()函数提供了更灵活的消息处理机制,而Linux则通过pipe等方式实现类似功能。
转载地址:http://fsllz.baihongyu.com/