对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决

本文探讨了使用WaitForSingleObject替代MsgWaitForMultipleObjects来解决线程中操作UI控件与等待消息之间的冲突问题,通过循环等待机制实现线程与UI消息的协调,确保程序流畅运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文来自:http://blog.csdn.net/silvervi/article/details/5874212

红色字为博主添加:

问题描述:AfxBeginThread创建一个线程后,在线程中操作UI的控件,例如EDIT。在UI的button里停止线程,并等待结束,一般用WaitforsingleObject,但是这个函数会导致UI消息阻塞,如果这个时候线程里正好操作UI控件并需要用到SendMessage,则线程在等待消息发送完,WaitforsingleObject在等待线程,而WaitforsingleObject又阻塞了消息,这样就导致了死循环。下文为解决方法,已经省略,全部可以参考原文地址:


还可以看出:MsgWaitForMultipleObjects实际上在这其中并没有起到什么实质性的作用,只是定期返回而已,那么根据此,可以用固定时间的WaitForSingleObject来代替MsgWaitForMultipleObjects,并且循环等待 ;同时,我们也没有必要手动DispatchMessage,只需要PeekMessage即可,需要注意的是如果删除了DispatchMessage,PeekMessage时不能将消息从队列取走。代码如下:


    DWORD dwRet = 0;  
    MSG msg;  
    while (TRUE)  
    {  
      dwRet = WaitForSingleObject(m_hThread, 50);  
      switch(dwRet)  
      {  
      case WAIT_OBJECT_0:   
        break; //break the loop  
      case WAIT_TIMEOUT :  
        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);  
        continue;  
      default:  
        break; // unexpected failure  
      }  
      break;  
    }  

      经过测试,代码运行正确!


      当然,由于MsgWaitForMultipleObjects是基于消息驱动的返回,WaitForSingleObject只是普通的定时返回,而本文的情况就是由于消息阻塞造成的,所以MsgWaitForMultipleObjects比WaitForSingleObject在应用时时效性更好,如果改成WaitForSingleObject,在测试中感觉会有略为滞后,所以实际还是以MsgWaitForMultipleObjects为佳。


### WinAPI WaitForSingleObject 等待线程退出 #### 使用方法 `WaitForSingleObject` 是 Windows API 中的一个重要函数,用于等待指定对象进入信号状态。对于线程而言,该函数可以用来等待某个线程的结束。此函数接受两个参数:第一个是要监视的对象句柄;第二个是指定的最大等待时间(毫秒)。如果设置为 `INFINITE` 则表示无限期等待直到目标事件发生[^2]。 #### 示例代码 下面展示了一个简单的 C++ 实现例子,在其中创建一个新的工作线程并通过调用 `WaitForSingleObject` 来等待其完成: ```cpp #include <windows.h> #include <stdio.h> DWORD WINAPI ThreadFunc(LPVOID lpParam) { printf("子线程正在运行...\n"); Sleep(2000); // 模拟耗时操作 printf("子线程已完成。\n"); return 0; } int main() { HANDLE hThread; DWORD threadId; // 创建新线程 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, NULL, 0, &threadId); if (hThread == NULL){ printf("CreateThread failed (%d)\n", GetLastError()); return 1; } // 等待线程结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 CloseHandle(hThread); printf("主线程继续执行。\n"); return 0; } ``` 这段程序首先定义了一个名为 `ThreadFunc` 的函数作为新的线程入口点。接着通过 `CreateThread()` 函数启动这个新线程,并保存返回的手柄到变量 `hThread` 中以便后续使用。之后调用了 `WaitForSingleObject()` 方法来暂停当前进程直至所关联的工作线程完成为止。最后关闭了不再需要的手柄以释放系统资源[^5]。 #### 解释 在这个案例里,当主应用程序到达 `WaitForSingleObject(hThread, INFINITE)` 这一行的时候会暂时停止进一步向下执行任何指令,而是持续监测由 `CreateThread()` 返回的那个手柄代表的状态变化情况。一旦被监控的目标——即这里指代的新建线程结束了它的生命周期,则原先处于挂起态下的 `WaitForSingleObject()` 调用就会恢复控制权给调用者,允许后面的语句得以正常顺序执行下去[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值