WaitForSingleObject与WaitForMultipleObjects用法详解(好用,而且进入一个非常高效沉睡状态,只占用极少的CPU时间片)
在多线程下面,有时候会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待Object被标为有信号(signaled)时才返回的。
那么,什么是信号呢?简单来说,Windows下创建的Object都会被赋予一个状态量。如果Object被激活了,或者正在使用,那么该Object就是无信号,也就是不可用;另一方面,如果Object可用了,那么它就恢复有信号了。这两个函数的优点是它们在等待的过程中会进入一个非常高效沉睡状态,只占用极少的CPU时间片。(这两个函数都是在内核状态下等待内核对象,不切换到用户模式下,因而效率很高)
WaitForSingleObject函数来等待一个内核对象变为已通知状态:
DWORD WaitForSingleObject( HANDLE hObject, //指明一个内核对象的句柄 DWORD dwMilliseconds); //等待时间
该函数需要传递一个内核对象句柄,该句柄标识一个内核对象,
如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;
如果该内核对象处于已通知状态,则该函数立即返回WAIT_OBJECT_0。
第二个参数指明了需要等待的时间(毫秒),可以传递INFINITE指明要无限期等待下去,
如果第二个参数为0,那么函数就测试同步对象的状态并立即返回。
如果等待超时,该函数返回WAIT_TIMEOUT。
如果该函数失败,返回WAIT_FAILED。可以通过下面的代码来判断
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- MessageBox( (LPCTSTR)lpMsgBuf);
- LocalFree( lpMsgBuf );
--------------------------------------------WaitForMultipleObjects()-------------------------------------------
- <span style="font-size:18px;">WaitForMultipleObjects()允许你在同一时间等待一个以上的对象。
- DWORD WaitForMultipleObject(
- DWORD nCount, //表示lphandles数组的元素个数
- CONST HANDLE *lphandles, //指向一个有对象handles组成的数组。
- BOOL bWaitAll, //如果为true,则表示所有的handles都必须激发,此函数才得以返回,否则,此函数将在任何一个handle激发时就返回。
- DWORD dwMilliseconds //超时也返回,可为0,立即返回,INFINITE表示无穷等待。
- );</span>
返回值:
如果因时间终了而返回,则返回值是WAIT_TIMEOUT,类似WaitForSingleObject().
如果bWaitAll是TRUE,则返回值将是WAIT_OBJECT_0.
如果bWaitAll是FALSE,那么将返回值减去WAIT_OBJECT_0,就表示数组中的哪一个handle被激发了。
如果你等待的对象中有任何mutexes,那么返回值可能从WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1.
如果函数失败,则返回WAIT_FAILED。可以使用GetLastError找出失败原因。
WaitForSingleObject测试方法:
- DWORD dw = WaitForSingleObject(hProcess, 5000); //等待一个进程结束
- switch (dw)
- {
- case WAIT_OBJECT_0:
- // hProcess所代表的进程在5秒内结束
- break;
- case WAIT_TIMEOUT:
- // 等待时间超过5秒
- break;
- case WAIT_FAILED:
- // 函数调用失败,比如传递了一个无效的句柄
- break;
- }
WaitForSingleObject测试方法:
WaitForMulitpleObjects函数来等待多个内核对象变为已通知状态:
- DWORD WaitForMultipleObjects(
- DWORD dwCount, //等待的内核对象个数
- CONST HANDLE* phObjects, //一个存放被等待的内核对象句柄的数组
- BOOL bWaitAll, //是否等到所有内核对象为已通知状态后才返回
- DWORD dwMilliseconds); //等待时间
该函数的第一个参数指明等待的内核对象的个数,可以是0到MAXIMUM_WAIT_OBJECTS(64)中的一个值。phObjects参数是一个存放等待的内核对象句柄的数组。bWaitAll参数如果为TRUE,则只有当等待的所有内核对象为已通知状态时函数才返回,如果为FALSE,则只要一个内核对象为已通知状态,则该函数返回。第四个参数和WaitForSingleObject中的dwMilliseconds参数类似。
该函数失败,返回WAIT_FAILED;如果超时,返回WAIT_TIMEOUT;如果bWaitAll参数为TRUE,函数成功则返回WAIT_OBJECT_0,如果bWaitAll为FALSE,函数成功则返回值指明是哪个内核对象收到通知。
可以如下使用该函数:
- HANDLE h[3]; //句柄数组
- //三个进程句柄
- h[0] = hProcess1;
- h[1] = hProcess2;
- h[2] = hProcess3;
- DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000); //等待3个进程结束
- switch (dw)
- {
- case WAIT_FAILED:
- // 函数呼叫失败
- break;
- case WAIT_TIMEOUT:
- // 超时
- break;
- case WAIT_OBJECT_0 + 0:
- // h[0](hProcess1)所代表的进程结束
- break;
- case WAIT_OBJECT_0 + 1:
- // h[1](hProcess2)所代表的进程结束
- break;
- case WAIT_OBJECT_0 + 2:
- // h[2](hProcess3)所代表的进程结束
- break;
- }
附:测试代码下载地址 :http://download.csdn.net/detail/makenothing/9497235
http://blog.csdn.net/makenothing/article/details/51197726
WaitForSingleObject与WaitForMultipleObjects用法详解(好用,而且进入一个非常高效沉睡状态,只占用极少的CPU时间片)的更多相关文章
- WaitForMultipleObjects用法详解
本文转载于:http://blog.csdn.net/sac761/article/details/52456385 WaitForMultipleObjects是Windows中的一个功能非常强大的 ...
- Ext.Net学习笔记22:Ext.Net Tree 用法详解
Ext.Net学习笔记22:Ext.Net Tree 用法详解 上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat=&q ...
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- C#中string.format用法详解
C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...
- @RequestMapping 用法详解之地址映射
@RequestMapping 用法详解之地址映射 引言: 前段时间项目中用到了RESTful模式来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没 ...
- linux管道命令grep命令参数及用法详解---附使用案例|grep
功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...
- mysql中event的用法详解
一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...
- CSS中伪类及伪元素用法详解
CSS中伪类及伪元素用法详解 伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
随机推荐
- 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?
在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...
- “我爱淘”冲刺阶段Scrum站立会议3
完成任务: 将搜索框的界面已经实现以及部署到整个框架中. 计划任务: 实现搜索功能,通过数据库的链接,实现用户可以查到自己需要的书籍的信息. 遇到问题: 1.数据库的操作,怎么实现查询功能: 2.Ac ...
- 学习笔记--HashMap浅析
HashMap 实现了Map 接口,其底层以一个线性数组保存哈希表,所以它既有数组查询的高效,也有哈希存取的方便. HashMap提供了默认构造器,和有参构造器,在有参构造器中,提供了两个参数,可以对 ...
- Log4j2 配置笔记(Eclipse+maven+SpringMVC)
Log4j2相关介绍可以百度看下,这里只注重配置Log4j2 能够马上跑起来: 1.pom.xml文件中添加Log4j2的相关Maven配置信息 <!-- log4j2 --> <d ...
- SQLServer BCP 命令的使用
现在有一个包含数据的文件,每个字段用“|”分隔,现在要把这些数据导入到数据库的表中. 数据文件如下: R001|20150710 可以使用如下命令: bcp testDB.dbo.testTable ...
- 防止IE7,8进入怪异模式
在页头添加 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- Ext.Ajax中scope的作用
在Ext的前台Js中使用Ajax请求,如果想让回调函数中的this作用域跟当前的类一样如何实现呢?Ajax提供了一个参数scope. 详细代码如下: layout : { type : 'accord ...
- USACO 4.1.2 栅栏的木料
这个讲的超好....一定要看...然后看我代码就好懂啦... http://blog.csdn.net/ta201314/article/details/41287567 各种优化确实非常好....搜 ...
- 【BZOJ】【3164】【HEOI2013】Eden的博弈问题
树形DP 这题在考场上直接写的TreeDP……当时也没想出一个像样的暴力来对拍……好像只能这么直接做了……? 都说是博弈树了,转移关系都给的这么直接了……也没啥难度了吧= =(怪不得大家都不愿意写题解 ...
- Http Module 介绍
引言 Http 请求处理流程 和 Http Handler 介绍 这两篇文章里,我们首先了解了Http请求在服务器端的处理流程,随后我们知道Http请求最终会由实现了IHttpHandler接口的类进 ...