在多线程编程中,通常都需要线程间的同步,一个线程要等待另一个线程的事件才继续执行,一般的做法是采用WaitForSingleObject和WaitForMultipleObjects()函数来实现。
但在实际的应用中,经常出现等待线程卡死的状况,也就是说等待的事件一直无效。为什么事件一直无效呢?很多的情况是等待线程阻塞了另外的线程,使另外的线程无法设置事件有效。为什么会阻塞呢?原因就比较多了,需要具体问题具体分析。

WaitForSingleObject和WaitForMultipleObjects()都是阻塞函数,事件无效就一直不返回,从而阻塞该线程,使该线程无法处理其他的事务,如果其他的线程发送消息过来,将得不到处理而不返回,从而将其他的线程也阻塞,造成相互等待,这就是臭名昭著的“死锁”!!!

微软提供了另外一个函数可以解决该问题,它就是MsgWaitForMultipleObjects()函数,该函数不但可以等待事件,还可以等待消息,从而处理消息,使线程不阻塞。该函数的具体解释前参考MSDN或网络。

一般的使用方法为:

[cpp] view plaincopy print?
  1. DWORD dwRet = 0;
  2. MSG msg;
  3. DWORD dwStartTime = GetTickCount();
  4. while (TRUE)
  5. {
  6. //超时判断  5s
  7. dwRet = GetTickCount() - dwStartTime;
  8. if ((GetTickCount() - dwStartTime) > 10000)
  9. {
  10. AfxMessageBox(_T("获取数据超时,请检测设备网络连接!"), MB_OK | MB_ICONERROR);
  11. return NULL;
  12. }
  13. //wait for m_hThread to be over,and wait for
  14. //QS_ALLINPUT(Any message is in the queue)
  15. //dwRet = WaitForSingleObject(g_hRetEvent, INFINITE);
  16. dwRet = MsgWaitForMultipleObjects (1, &g_hRetEvent, FALSE, 100, QS_ALLINPUT);
  17. switch(dwRet)
  18. {
  19. case WAIT_OBJECT_0: //返回数据达到
  20. break; //break the loop
  21. case WAIT_OBJECT_0 + 1: //界面消息
  22. //get the message from Queue
  23. //and dispatch it to specific window
  24. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  25. {
  26. TranslateMessage(&msg);
  27. DispatchMessage(&msg);
  28. }
  29. continue;
  30. case WAIT_TIMEOUT: //超时
  31. continue;
  32. default:
  33. AfxMessageBox(_T("数据获取失败,未知错误!"), MB_OK | MB_ICONERROR);
  34. return NULL;
  35. break; // unexpected failure
  36. }
  37. break;
  38. }
DWORD dwRet = 0;
MSG msg;
DWORD dwStartTime = GetTickCount();
while (TRUE)  {
//超时判断  5sdwRet = GetTickCount() - dwStartTime;
if ((GetTickCount() - dwStartTime) > 10000)
{
AfxMessageBox(_T("获取数据超时,请检测设备网络连接!"), MB_OK | MB_ICONERROR);
return NULL;
}//wait for m_hThread to be over,and wait for
//QS_ALLINPUT(Any message is in the queue) //dwRet = WaitForSingleObject(g_hRetEvent, INFINITE);
dwRet = MsgWaitForMultipleObjects (1, &g_hRetEvent, FALSE, 100, QS_ALLINPUT);  switch(dwRet)
{
case WAIT_OBJECT_0: //返回数据达到
break; //break the loop
case WAIT_OBJECT_0 + 1: //界面消息
//get the message from Queue  //and dispatch it to specific window
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
continue;
case WAIT_TIMEOUT: //超时
continue;
default: AfxMessageBox(_T("数据获取失败,未知错误!"), MB_OK | MB_ICONERROR);return NULL;
break; // unexpected failure
} break;
}

特别是在主线程和界面线程中推荐使用该函数,可以避免很多麻烦!!!

用MsgWaitForMultipleObjects代替WaitForSingleObject和WaitForMultipleObjects()相关推荐

  1. 在用户线程/主线程中推荐MsgWaitForMultipleObjects代替WaitForSingleObject和WaitForMultipleObjects()函数

    在多线程编程中,通常都需要线程间的同步,一个线程要等待另一个线程的事件才继续执行,一般的做法是采用WaitForSingleObject和WaitForMultipleObjects()函数来实现. ...

  2. WaitForSingleObject与WaitForMultipleObjects用法详解

    WaitForSingleObject与WaitForMultipleObjects用法详解

  3. WaitForSingleObject和WaitForMultipleObjects用法

    转自:http://www.360doc.com/content/10/0512/09/1072296_27178529.shtml 等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知 ...

  4. Windows线程CreateThread、线程处理函数、SuspendThread、ResumeThread、WaitForSingleObject、WaitForMultipleObjects

    Windows线程是可以执行的代码的实例.系统是以线程为单位调度程序.一个程序当中可以有多个线程,实现多任务的处理. windows线程的特点: 1.线程都具有一个ID 2.每个线程都具有自己的内存栈 ...

  5. 线程函数的设计以及MsgWaitForMultipleObjects函数的使用要点

    使用多线程技术可以显著地提高程序性能,本文就讲讲在程序中如何使用工作线程,以及工作线程与主线程通讯的问题. 一 创建线程 使用MFC提供的全局函数AfxBeginThread()即可创建一个工作线程. ...

  6. 多线程和MsgWaitForMultipleObjects

    在主线程中慎用WaitForSingleObject (WaitForMultipleObjects) 下面的代码我调试了将近一个星期,你能够看出什么地方出了问题吗? 线程函数: DWORD WINA ...

  7. Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析

    Windows事件等待学习笔记(三)-- WaitForSingleObject函数分析 要点回顾 WaitForSingleObject NtWaitForSingleObject KeWaitFo ...

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

    今天在调试程序中发现了程序中出现的一个问题,具体如下: 在对话框中新建一个线程worker thread,当用户点击cancel时,通知该线程函数退出,同时用WaitForSingleObject等待 ...

  9. 事件EVENT与waitforsingleobject的使用以及Mutex与Event的区别

    Mutex与Event控制互斥事件的使用详解最近写一程序,误用了Mutex的功能,错把Mutex当Event用了.[Mutex]使用Mutex的主要函数:CreateMutex.ReleaseMute ...

最新文章

  1. [JS-BOM]BOM_Location地址栏对象
  2. html中内容超出显示省略号的方法
  3. 华为正加大全球招聘 包括芯片工程师、软件开发员和AI研究员
  4. 银行家算法 计算机操作系统,计算机操作系统 银行家算法.doc
  5. iOS开发UI调试神器----Reveal
  6. ubuntu下搭建车场环境(代码使用jekins构建)
  7. 八、属性和方法(属性和方法的概念以及使用,注意,新特性中的自动属性,方法的重载)...
  8. ABAP TRANSPORTING NO FIELDS 用法
  9. Jquery实现AJAX异步通信
  10. SSM在线车队货车管理系统
  11. enable 华为交换机ntdp_ntdp enable在配置里面是什么意思
  12. 2021上海L Three,Three,Three(一般图匹配)
  13. [BD 41-758] The following clock pins are not connected to a valid clock source
  14. 面向游戏玩家的六款最佳Linux发行版
  15. 如何在零件层隐藏/显示SOLIDWORKS尺寸?
  16. c503 如何设置上网和彩信
  17. 企业抖音如何运营,抖音企业号能给商家带来什么?
  18. IPv6公共DNS现在提供加密DNS查询
  19. 特斯拉持续涨价,中国制造可望因此受益
  20. modbus转profinet网关连接ABB变频器在博图程序案例

热门文章

  1. 埃夫特机器人回零偏差太大_新松、华中数控、埃斯顿、埃夫特国内主流机器人厂商近年最新动态...
  2. redis延迟队列 如何确保成功消费_千万级延时任务队列如何实现,看美图开源的-LMSTFY...
  3. docker镜像内容如何查看_如何快速打通 Docker 镜像发布流程?
  4. 电脑f2还原系统步骤_电脑一键还原win10系统的操作步骤
  5. 2020-11-30 离散系统自适应控制中的一个关键性引理及证明
  6. ElasticSearch优化系列三:机器设置(内存)
  7. ThinkPHP3.2 G函数代码及 使用方法
  8. webBrowser1_DocumentCompleted不停被调用
  9. 趣味英语 恐怖的单词
  10. arcgis api for js图层显示控制