Chinaunix首页 | 论坛 | 博客
  • 博客访问: 407318
  • 博文数量: 57
  • 博客积分: 193
  • 博客等级: 入伍新兵
  • 技术积分: 1192
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-13 14:37
个人简介

当以艺术眼光看程序,寻找程序后面的原理,做到化而不忘

文章分类

全部博文(57)

文章存档

2017年(5)

2015年(7)

2014年(27)

2013年(18)

我的朋友

分类: Windows平台

2014-06-07 17:51:51


记得第一份工作,发动机控制器,做项目时,软件要从EEP中读取512B数据到单片机内部建立映像,这样就可以在运行过程中,只修改EEP映像值,避免对对外界的物理EEP访问,在钥匙关闭以后,再一次性将所有的512B数据写到EEP中。当时水平很菜,钥匙上电时,一次性读取所有的数据,耗时很长,大概100多个ms,读取数据时,程序是卡在那里,直到EEP数据读取完全,程序再向下运行,完全是阻塞的,写入时也是这样,程序也是阻塞的,直到写完程序才会向下走。还好这个项目只是领导玩玩,领导不当真,所以程序写得很烂,也没什么事。

现在回头想想,觉得好笑,完全阻塞式的设计,那性能是要大大地降低了,最近看Windows内核方面的资料,发现在OS中,异步机制很常见,也很有用,比如读取文件,如果文件比较大或者时序要求严格,那可不能老是停止在ReadFile那里,所以此函数提供了异步读取功能,通过填写一个Overlap结构体,写入你的回调函数就可实现异步。

说到异步,和中断有点像,但是又有区别。中断对CPU来说,完全是突然的,事先没有任何通知,所以现代CPU对中断还是比较配合的,具体体现在,当中断发生时,CPU会保存一些关键信息到栈中或寄存器中,典型地,当中断发生时,X86会向内核栈中保存当前中断的向量号,保存用户态CSIPSS等等寄存器以备中断后返回到用户态,这些是CPU自动保存的。而异步,则某种程序上,是软件来实现的一个机制,是为了系统的性能考虑而提供的一个功能,具体设计取决于软件。

在看Windows内核时,发现异步实现有三种方式(水平有限,只看到这三种,如果有错误,请指教):

1APC

2DPC

3:内核劳务线程

APCDPC名词意义就不说了,不知道的Baidu一下。内核劳务线程比较好理解,就是内核在初始化时,就生成一个线程队列,周期性执行,它们负责一些日常工作,比如实现很有名的IO完成端口功能。说到这里,结合我的实际工作,我们完全可以在系统添加一个类似的线程或函数,来做些辅助性工作,比如实现看门狗的功能,或实现EEP的读写,这样,在上层只要发现读写EEP的请求,并将相应的数据及地址 以参数的形式传递给辅助线程或函数,这样就可以实现异步机制了。

再说说APC,它分为用户APC和内核APC,用户APC的执行时机是系统调用返回时,为什么在这里?我觉得可能是基于这样考虑的,系统调用时,会执行些内核操作,比如读取文件,或从网卡上取数据,系统调用返回时,调用用户APC,给人的感觉是,系统调用完成了任务,然后调用用户APC通知用户,事件做完了,你可以继续了。

内核APC是在IRQL降低时调用的,为什么在这里调用呢?可能原因是这样,IRQL上升是中断发生,IRQL下降可以认为是中断完成,中断完成后调用APC也是起到通知及后事处理作用,当然了IRQL下降也不全是中断完成引起的,它现在也作为线程调度的一个手段了,IRQL下降时,会检测APCDPC,调用其例程。这样看来,IRQL可以当成一个栈,IRQL的下降时,比如从CLOCK_LVEVL下降到APC_LEVEL,经过DPC_LEVELAPC_LEVEL时,调用其例程可以当成路过时的回调函数。

阅读(1991) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

CUTianrui0072014-06-09 21:15:34

irp:不管是user/kernel APC, 主要都是为一个目的,asynchronous I/O. user APC => completion user of part, kernel APC => completion of kernel part, kernel APC 后来衍生其他的用处,需要在process context下完成不是很紧急的任务,比如suspend thread etc.

多谢指导!

回复 | 举报

irp2014-06-09 19:53:43

不管是user/kernel APC, 主要都是为一个目的,asynchronous I/O. user APC => completion user of part, kernel APC => completion of kernel part, kernel APC 后来衍生其他的用处,需要在process context下完成不是很紧急的任务,比如suspend thread etc.