APC异步过程调用

转自:http://blog.sina.com.cn/s/blog_c2ef450f010192hx.html

APC 异步过程调用

 

记得第一次看见这个名词的时候,觉得云里雾罩,然而上网看了下它的介绍,感觉说的都是没头没脑的

然而今天,我再次接触了它,我将自己对其的理解写下,若有不对,欢迎指正(参照《windows核心编程 》第五版)                狼影 --------- 20131018

好啦,废话少说,让我们进入正题:

 

首先我们应该明白的是在创建线程的时候,这个所谓的APC就已经建立,并且与线程相关联,并且这个APC是个队列;

队列中项的产生:

那么是谁往队列里面添加内容呢,这个就要说到设备驱动程序了,现在是不是感觉不知所以然,听我慢慢讲来; 当一个线程发出一个I/O请求时(在这里我们讲的是异步I/O请求哦),设备驱动程序接收它的请求,那么线程呢就执行自己剩下的工作(直到某一点,它实在是执行不去(因为在这点必须要得到请求的I/O结果)),那么设备驱动程序在执行完I/O请求后,他怎么让线程直到他已经执行完I/O了呢?

那就是它会在APC队列中添加一项,那么问题又来啦,它又怎么会知道往这个线程中的APC队列中添加项呢,嘿嘿,这当然是线程告诉他的,在哪告诉的呢,当然是在发送I/O请求时告诉的,在这我也不卖官司啦,直接说啦,线程在请求I/O操作时用的是ReadFileEx()或者WriteFileEx()函数,这两个函数在发送I/O请求的时候,就告诉设备驱动程序,说嗨,哥们,你处理完我的请求后,就把通知发送到我的APC队列中啊,哥等你”; (当然这个队列项的内容就是那个完成函数的地址和在I/O请求时那个OVERLAPPED结构的地址(至于什么是完成函数和OVERLAPPED结构,我想就不用多说了把)),

这下我们知道了APC队列中项的由来,那么接下来我们要了解的是项的处理:

在项添加到APC队列中时,它不会被马上处理,(线程在有其他任务处理的情况下不能被打断为了对线程APC队列中的项进行处理,线程必须将自己置为可提醒状态)

那么什么是可提醒状态,怎么才能设为可提醒状态呢?

可提醒状态在我感觉他就是为了处理APC中的项而出来的概念,因为在队列中有项的情况下,线程会处理那些项,而当APC队列中没有项的时候,那么线程就会是挂起状态;(在我看来,这里的可提醒应该是通知的意思,就是通知APC队列中有项,让它处理 记住!当且仅当线程的APC队列中一项都没有的情况下线程才会挂起

至于怎么让线程成为可提醒状态,windows为我们提供了6个函数

SleepEx()

WaitForSingleObjectEx()

WaitForMultiObjectEx()

SignalObjectAndWait()

GetQueuedCOmpletionStatusEx()

MsgWaitForMultipleObjectEx()

前五个函数的参数中最后一个参数是个BOOl值,表示调用线程是不是应该将自己置为可提醒状态

对于最后一个函数的最后一个参数我们应该使用MWMO_ALERTABLE标志来让线程进入可提醒状态

 

还有一点是,当线程在挂起状态时,将其唤醒的方法可以是等待内核对象的触发,或者也可以在APC队列中出现一个项,当一个项出现的情况下,系统会唤醒我们的线程(通过回调函数)并清空队列,然后函数会立即返回---线程不会再次进行睡眠状态来等待内核对象被触发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值