首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

对 Windows 中未公开的对象 —— 事件对(EventPair)的范例探究

2012-10-12 
对 Windows 中未公开的对象 —— 事件对(EventPair)的实例探究广大Win32程序员都对Windows SDK中的事件(Even

对 Windows 中未公开的对象 —— 事件对(EventPair)的实例探究
广大Win32程序员都对Windows SDK中的事件(Event)对象不陌生,这个是2个线程同步经常使用的东西,用法想必我也不需要多说了,可Windows中还有一个离奇的对象,叫做事件对(EventPair),关于这个对象不管是SDK还是MSDN都没有任何介绍,网上的资料也不多,很多人可能连这个对象是干啥的都不知道,这篇文章笔者就跟大家一起来看看这个神秘的EventPair对象。

基于:ReactOS的Doxygen文档参考
环境:Windows NT 6.1、Visual Basic 6.0

事件对的由来
在Windows 98和Windows NT 3.X年代,Windows中的环境子系统(csrss)进程还负责着Windows的图像图形系统核心的任务,其他任何程序需要在屏幕上绘图,系统都需要通过IPC手段通知csrss让其根据相关数据去绘制,所以其他Windows程序进程跟csrss的通讯效率就至关重要,这里微软的程序员就为了csrss的高效通讯加入了一种内核对象,就是现在一直都存在并且再也不会更新的“EventPair”对象。
而后Windows NT将绘图的任务移入了内核模块win32k.sys,csrss肩负的东西一下就少了很多,到现在在绘图上面也仅仅是承担着对控制台窗口的图像绘制任务,但当年那个为了csrss而设置EventPair对象则一直存在于Windows内,并且直到今天的Win7、Win8。
而又由于这个对象本是为了csrss而设置的,而csrss很快又“残疾”了,所以现在微软依然没有把这个对象的相关接口公开进Win32 API里面,不过那么多年过来了,虽然这个对象没有更新功能接口,不过看样子微软也不准把它删掉,所以大家也可以放心的在自己的程序里使用。(注:商业程序请慎重考虑)
而为什么又叫做Pair呢?因为一个EventPair对象就是2个Event对象,有“高位”和“低位”之分,分别给Server\Client使用,就像老公老婆一样。。。

事件对的用处
上面已经说了,csrss当年是一个所有程序的绘图任务“服务端”(现在也承担着不少任务的服务端功能),而事件对本就是为了其他程序跟csrss进行高效率的C\S通讯而设置的,所以事件对这个东西比较适用于2个进程间的通讯,而不是2个线程,2个线程间(或N个)用Event对象就好了。
要说“事件对”的功能,则我们还是先回顾一下Win32中的“事件”的功能:
1、有一个进程内全局事件对象hEevnt
2、有二个线程:线程A、线程B
3、线程A需要线程B处理一个任务,线程B处理的任务完成前,线程A进入等待状态(等待线程B的通知),此时线程A调用Win32中的Wait函数,等待hEvent
4、线程B进入处理,处理完毕,复位hEvent,线程A立马接到通知,退出等待,向下执行。
然后事件对的功能则是:
1、有一个系统内全局事件对象hEventPair
2、有二个进程:服务端、客户端
3、此时服务端、客户端都访问了这个系统级的全局事件对象hEventPair,它们之间就形成了一个“事件对”的情况
4、客户端给服务端发送请求(通过hEventPair),要求服务端处理一个任务,服务端处理完成前,客户端进入休眠等待状态,等待服务端处理完毕的通知
5、服务端接到通知,根据hEventPair是哪个对象,决定处理哪个任务(或其他判断方法),服务端进入处理,处理完毕,给客户端发送一个消息(通过hEventPair),客户端的等待线程接到通知,立马知道服务端已经处理完毕,客户端休眠的线程代码继续向下执行
【上面的客户端和服务端的通讯情况也可以“倒过来”,也就是说EventPair是双向的】

可以说事件对是2个进程间的“事件”对象功能的实现,而且因为csrss的原因,专门针对本地的C\S架构进行了优化。

事件对的接口
由于微软没有公开Win32接口,所以仅有系统调用,当然这个算是所有系统调用的对象里面比较简单的了。。。
NtCreateEventPair:创建一个事件对对象,这个对象任何进程都能访问
NtOpenEventPair:根据命名空间字符串打开一个事件对对象
NtWaitHighEventPair:等待事件对对象中的“高位”对象
NtWaitLowEventPair:等待事件对对象中的“低位”对象
NtSetHighEventPair:通知高位对象
NtSetLowEventPair:通知低位对象
NtSetHighWaitLowEventPair:通知高位对象并且马上进入等待低位对象
NtSetLowWaitHighEventPair:通知低位对象并且马上进入等待高位对象

以上函数的原形,我下面的代码有VB6版本的声明,C style的原形请参看谷歌或ReactOS的代码。

事件对的创建

一个EventPair对象通过系统调用函数NtCreateEventPair创建,NtCreateEventPair有3个参数,第一个是一个DWORD指针,返回EventPair对象的句柄;第二个参数是访问权限,一般都是EVENT_PAIR_ALL_ACCESS;第三个参数是一个内核通用的结构体OBJECT_ATTRIBUTES的指针,注意这个参数虽然是可选的,而在跨进程的C\S架构情况中,OBJECT_ATTRIBUTES结构的ObjectName则必需不是一个NULL,因为没有一个命名空间,其他进程无法访问到这个EventPair对象。

下面是一个EventPair对象的创建代码:



转载请注明出处【a1875566250 原创:http://blog.csdn.net/a1875566250/article/details/8034375】

热点排行