《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“事件内核对象”...
本书首先介绍了一个重要的概念“成功的副作用”,这里笔者作一下简述。
当调用WaitForSingleObject和WaitForMultipleObject函数成功之后,该函数在返回成功的时候,系统可能会自动更改所等待的内核对象的状态,即将其从“已通知状态”切换为“未通知状态”。
当一个内核对象的状态被更改,称之为“成功等待的副作用”。比如,一个“自动重置”的事件内核对象,当调用等待函数成功返回的时候,该事件内核对象会由已通知状态转变为未通知状态。
比如此时有一个自动重置的事件内核对象hEvent,它处于未通知状态。线程T1、T2、T3内部调用“WaitForSingleObject(hEvent, INFINITE);”,这样当该事件内核对象变为“已通知”状态的话,T1线程“可能”被唤醒,但是其他的线程T2和T3呢?由于在T1线程内部WaitForSingleObject函数返回成功,又将hEvent事件内核对象设置为“未通知”状态,那么T2和T3就不可能被唤醒。
也就是说,“成功等待的副作用”会导致多个等待在同一个内核对象上的线程只能被唤醒一个。
好,下面我们来讨论“事件内核对象”。
在所有内核对象中,事件内核对象是最基本的一个内核对象。在事件内核对象内部,有以下几个比较重要的数据:
1、有一个“引用计数”:指明被打开的次数;
2、一个“布尔值”:指明该事件内核对象是自动重置的还是人工重置的;
3、另一个“布尔值”:指明该事件内核对象是“已通知状态”还是“未通知状态”。
事件内核对象可以通知一个事件已经完成。有两种不同的类型:自动重置和人工重置。当人工重置的事件内核对象得到通知的时候,所有等待在事件内核对象上的线程都变成可调度线程。当一个自动重置的事件内核对象得到通知的时候,等待在该事件内核对象上的线程只有一个能变成可调度状态。
要使用事件内核对象,首先调用CreateEvent函数来创建一个事件内核对象:
PSECURITY_ATTRIBUTES psa,
BOOL bManualReset,
BOOL bInitialState,
PCTSTR pszName);
参数psa是一个SECURITY_ATTRIBUTES(安全属性)结构的指针,一般设置为默认安全,传递NULL。
bManualReset参数指定了该内核对象是人工重置(传递TRUE)的还是自动重置(传递FALSE)的。
bInitialState参数指定了该内核对象起始状态是已通知(传递TRUE)还是未通知状态(FALSE)。
pszName参数为要创建的事件内核对象起一个名字,如果传递NULL,则创建一个“匿名”的事件内核对象。如果不传递NULL,且系统中已经存在该名字的事件内核对象,则不创建新的事件内核对象而是打开这个已经存在的,返回它的句柄。
该函数如果成功,返回事件内核对象的句柄,这样就可以操纵它了。如果失败,返回NULL。
Windows Vista提供了另一个函数来创建事件内核对象:
PSECURITY_ATTRIBUTES psa,
PCTSTR pszName,
DWORD dwFlags,
DWORD dwDesiredAccess);
该函数的psa和pszName参数的意义和函数CreateEvent相同。
参数dwFlags可以有以下数据的“位或组合”:
WinBase.h中定义的位组合数据 |
描述 |
---|---|
CREATE_EVENT_INITIAL_SET (0x00000002) |
如果设置了该数据,则表明事件内核对象的起始状态为已通知状态;否则起始状态为未通知状态。 |
CREATE_EVENT_MANUAL_RESET (0x00000001) |
如果设置了该数据,则表明事件内核对象是人工重置的;否则为自动重置的。 |
参数dwDesiredAccess可以让你对该事件内核对象的访问加一些限制,本书没有细说,查MSDN就可以了吧。
可以打开一个“命名”的事件内核对象:
DWORD dwDesiredAccess,
BOOL bInherit,
PCTSTR pszName);
第一个参数指明的访问的限制,第二个参数表示该事件内核对象的句柄能够被子进程继承,第三个参数指明了该事件内核对象的名字。该函数成功返回事件内核对象的句柄,失败返回NULL。
当不需要使用这些句柄时,需要调用CloseHandle函数来递减内核对象的引用计数,使得该内核对象可以被及时清除。
当一个事件内核对象被创建之后,你可以直接控制它的状态。你可以通知它,使得它从未通知状态转变为已通知状态:
也可以重新设置它,使它从已通知状态变为未通知状态:
一个自动重置的事件内核对象,如果等待成功,由于“成功等待的副作用”机制会将该事件内核对象由已通知状态变为未通知状态,这个时候就没有必要调用ResetEvent函数了。
如果是一个人工重置的事件内核对象,等待成功之后,并不会被设置为未通知状态,而是要程序员调用ResetRvent函数来使之转变为未通知状态。
还有要注意的就是,一个“自动重置”的事件内核对象收到通知,转变为已通知状态的时候,最多只能唤醒“一个”等待在它上的线程。一个“人工重置”的事件内核对象收到通知,转变为已通知状态的时候,能够唤醒“所有”等待在它上的线程。
转载于:https://www.cnblogs.com/wz19860913/archive/2008/08/11/1265090.html
《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“事件内核对象”...相关推荐
- Chapter09-内核模式下的线程同步之事件内核对象
有两种事件内核对象:自动事件和手动事件.当手动事件被触发时,所以该事件的等待线程都编程可调度状态:而自动事件被触发时,只有个一个等待该事件线程变成可调度状态. 下面再逐个讲解Event的相关函数: a ...
- muduo学习笔记 - 第2章 线程同步精要
第2章 线程同步精要 2.1 互斥器 (mutex) 互斥器保护了临界区,任何时刻最多只能有一个线程在mutex划出的临界区内活动 推荐使用原则: 用RAII手法封装mutex的创建.销毁.加锁.解锁 ...
- Windows驱动开发学习笔记(七)—— 多核同步内核重载
Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...
- Windows事件等待学习笔记(二)—— 线程等待与唤醒
Windows事件等待学习笔记(二)-- 线程等待与唤醒 要点回顾 等待与唤醒机制 可等待对象 可等待对象的差异 线程与等待对象 一个线程等待一个对象 实验 第一步:编译并运行以下代码 第二步:在Wi ...
- Windows进程与线程学习笔记(八)—— 线程切换与TSS/FS
Windows进程与线程学习笔记(八)-- 线程切换与TSS/FS 要点回顾 线程切换与TSS 内核堆栈 调用API进0环 实验:分析SwapContext 线程切换与FS 段描述符结构 分析Swap ...
- [转]Windows平台下Makefile学习笔记
Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...
- Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写
Windows进程与线程学习笔记(九)-- 线程优先级/进程挂靠/跨进程读写 要点回顾 线程优先级 调度链表 分析 KiFindReadyThread 分析 KiSwapThread 总结 进程挂靠 ...
- Windows进程与线程学习笔记(六)—— 线程切换
Windows进程与线程学习笔记(六)-- 线程切换 主动切换 分析KiSwapContext 分析SwapContext 分析KiSWapThread 总结 时钟中断切换 系统时钟 分析INT 0x ...
- oracle查询数据做标记,【学习笔记】Oracle如何使用dbms_shared_pool.markhot标记热对象...
[学习笔记]Oracle如何使用dbms_shared_pool.markhot标记热对象 时间:2016-10-30 20:17 来源:Oracle研究中心 作者:HTZ 点击: 次 天 ...
- Windows核心编程:第9章 用内核对象进行线程同步
Github https://github.com/gongluck/Windows-Core-Program.git //第9章 用内核对象进行线程同步.cpp: 定义应用程序的入口点. //#in ...
最新文章
- 一键安装python3环境
- Codepen 每日精选(2018-4-22)
- python json转换字典_Python json转字典字符方法实例解析
- P2280 [HNOI2003]激光炸弹
- 【数字逻辑设计】判断二进制加法溢出的电路设计
- uva 10048 Audiophobia(最小生成树)
- Akka的Actor生命周期《Eight》译
- 笔记_pytorch
- 程序批量将文本文件中的某字符替换
- 二元函数对xy同时求导_《高等数学》微课视频“二元函数的全微分求积”录音...
- 在线股票配资配资股票交易整站源码/牛股跟投带实盘策略区块链网站整站源码
- 中国眼下拥有的人造卫星的种类及其作用
- 小程序自动定位当前位置
- 强化学习蘑菇书Easy RL第一章
- android 支付宝sdk接入详解
- matlab lpc求共振峰频率,共振峰检测算法研究与实现
- 光纤收发器测试方法大全
- sql基础_SQL基础
- 撬动PMBOK6运用指南第九章
- Python爬虫入门实战,图文详细教学,一看就懂