首页
社区
课程
招聘
[旧帖] [原创]Windows驱动开发技术详解学习笔记---同步调用和异步调用的执行顺序(单一请求) 0.00雪花
发表于: 2010-10-10 19:35 3579

[旧帖] [原创]Windows驱动开发技术详解学习笔记---同步调用和异步调用的执行顺序(单一请求) 0.00雪花

2010-10-10 19:35
3579

一个月前开始学习Windows驱动开发,断断续续将《Windows驱动开发技术详解》这本书概读了两遍,将其中的一些体会分享给大家,这次介绍一下最简单的同步调用和异步调用的执行顺序问题。
我们知道驱动基本上由DriverEntry例程(这里引用书上的术语,就不称作函数了)和若干派遣例程组成,这里只讲最简单的,其余的以后再说。
DriverEntry例程是由System进程在驱动被加载的时机被调用的。其中主要注册派遣例程,以方便后续的用户进程能够访问它们。

同步这个概念就不说了,我们来看看下面基本的4种调用。
1)同步调用(驱动支持同步模式)
这种情况下,同步等待是由Windows来负责等待操作的完成,而驱动仅仅在派遣例程中的调用IOCompleteRequest来完成该操作。


2)异步调用(驱动支持同步模式)
这种情况下,同步等待是Windows就不负责了,等待必须由用户负责,而驱动仅仅在派遣例程中的调用IOCompleteRequest来完成该操作。
从这里可以看到,如果驱动层只支持同步模式的话,应用程序使用同步和异步没有多大驱动,因为当前调用返回值,底层动作已经完毕。反而多了等待事件的操作,还不如用同步方式。

这里需要强调一下,在派遣例程返回之前,用户的IO调用是不会返回的。好像好多人对此不是很理解。


3)同步调用(驱动支持异步模式)
和1)一样,同步等待是由Windows来负责等待操作的完成,不过在派遣例程返回时,该IO操作还没有完成。等到后续的DPC例程执行完时,本次IO操作才算完毕,用户的的调用这时候才真正返回。
这里需要注意的有两点:
一:DPC的执行线程上下文已经不一定是该调用的用户线程,因此有些需要访问用户内存空间的代码就会出问题了。
二:DPC的执行级别是在DISPATCH_LEVEL上的,执行期间不会发生线程切换。(书上这么说的,不过如果在其中有等待操作的话,还是会发生线程切换的,因为是当前线程主动放弃CPU时间的。
【当前线程<线程甲>:我是无辜的,为什么让我暂停!!! <----没名字的家伙,停的就是你-_-】)

4)异步调用(驱动支持异步模式)
从图上可以看到,只有在这种方式下,用户才能在底层执行的同时来做点兼职工作。


介绍完基本的调用方式,我们把取消例程加上后再分析一下。由于仅支持同步模式的驱动以及用户同步调用时,IO操作已经完成,因此这里只考虑异步调用(驱动支持异步模式)方式。
其中可以分为取消成功和取消失败两种情况:
1)取消成功
我们将上面的兼职工作修改成取消IO操作,从图上可以看到,驱动执行Cancel例程时,会将DPC例程取消,同时将本次IO操作以Cancelled返回。然后用户继续等待事件,当然也已经将信号设置上了。
注意,虽然已经调用了CancelIO,但是,等待事件不可跳过,因为还有取消失败的情况发生。
还有Cancel例程的运行级别是在APC_LEVEL上的。


2)取消失败
我们发现,Windows打算执行Cancel例程时,本次IO操作已经完毕。该请求已经不存在了,当然以失败而告终。
注意DPC中应该将该IO操作的Cancel例程指针设定为NULL。


到此为止,上述的执行顺序还算比较简单,原因是用户调用还处于单线程模式下。
下面稍微加大一点难度,我们把CancelIO的调用移动到另外一个线程中去,这样CancelIO的调用时机点和本次IO操作的重叠契机又多了两种情况。我们先来看看和单线程相同的两种情况。
除了Cancel例程在另一个线程上下文中执行之外,和单线程方式没啥区别。
1)取消成功

2)取消失败


多出来的两种情况是,IO操作执行过程中(IO调用还未返回),由另一个线程取消本次IO。这里也会存在两种情况,成功或者失败。
1)取消失败
IO操作还未到达派遣例程时,当然调用无效啦,就像平白无辜调用CancelIO一样。见图。


2)取消成功
这次的情况是两个例程赶到一块去了,大家注意做好同步控制。具体还得看派遣例程内部如何实现。实现得好的话,这种情况和上面的某一种属于同一类。


到此为止,有几个概念需要明确一下。
1)例程
有时可以把它当作用户态的线程在内核上的一种映射。当然不一定是一对一的。
2)运行级别(IRQL)
书上也有介绍,大家记住处于DISPATCH_LEVEL的运行级别下是不会发生线程切换的就行。
不过有一点书上也没有提到,就是处理APC_LEVEL的运行级别下会不会发生线程切换呢?好像网上也没有找到答案。

由此看来,只要掌握同步和异步的概念,并且对系统已线程为单位进行执行的基础知识没有问题的话,也不是很难理解的。
关于多IO操作的StartIO例程的执行顺序,下回学好了再写,今天就到此为止,希望大家共同进步。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主辛苦,先顶再看
2010-10-10 19:43
0
雪    币: 13
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
哇,快学到这里了,先看下,楼主加油
2010-10-10 19:45
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我怎么才能成为正式的会员啊
2010-10-10 21:32
0
雪    币: 70
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习学习。一起加油
2010-10-10 21:41
0
雪    币: 307
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
好东西,看看
2010-10-10 22:05
0
雪    币: 255
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
学习了·······
2010-10-10 23:58
0
雪    币: 255
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看看有多少了·····
2010-10-11 00:24
0
雪    币: 693
活跃值: (108)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
楼主又见面了,异步调用的取消成功部分驱动执行Cancel例程时,会将DPC例程取消,同时将本次IO操作以Cancelled返回,既然将DPC例程取消,那么事件如何被设置上的,DPC例程为何会取消,图的右下部分看的不太明白,烦请解释。
另还烦请您将StartIo部分的早点写出来吧,期待中!
2010-10-11 12:51
0
雪    币: 83
活跃值: (43)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
IoCompleteRequest内部会将事件设定。

DPC的启动和取消属于实现的细节了。举例如下:
启动DPC用KeInitializeTimer,KeInitializeDpc和KeSetTimer实现。
取消DPC用KeCancelTimer实现。

另外平时要上班,得看有没有足够的时间了,最迟这周末为止应该能写出来了。
其实也不是很难的。主要时间花在画图上了-_-。
2010-10-11 21:13
0
雪    币: 1103
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
顺便看看我有多少积分
2010-10-11 21:52
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
楼主辛苦了。先顶再看
2011-4-25 12:55
0
雪    币: 67
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
一直想搞驱动诶,就是现在没时间啊,学习了先。
2011-4-25 13:59
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
lz辛苦了
2011-4-28 09:54
0
游客
登录 | 注册 方可回帖
返回
//