Windows核心编程(十)异步设备I/O

1、设备IO与CPU速度甚至是内存访问相比较都是比较慢的,而且更不可预测。虽然如此,通过使用异步设备IO我们仍然能够创造出更高效的程序。

同步IO时,发出IO请求的线程会被挂起。而异步IO时发出请求的线程不会被挂起,而是可以继续执行。异步IO请求传给了设备驱动程序,被加入到驱动程序的请求队列中,驱动程序负责实际的IO操作。当设备驱动程序完成了对队列中IO请求的处理,无论成功与否都必须通知应用程序。

异步IO非常关键的一点就是将IO请求加入驱动程序队列,这是设计高性能可伸缩应用程序的本质所在。

为了以异步的方式来访问设备,首先在调用CreateFile时,必须传给dwFlagsAndAttributes参数

FILE_FLAG_OVERLAPPED标志。这个标志告诉系统我们想要以异步的方式来访问设备。

其次,还需要将IO请求加入设备驱动程序的队列。我们需要ReadFile和WriteFile两个函数。这两个函数会检查hFile参数标识的设备是否FILE_FLAG_OVERLAPPED标志打开的。如果指定了这个标志,那么函数会执行异步设备IO。时,可以传NULL给CreateFile和WriteFile的pdwNumBytes参数,因为它们会立即返回,检查pdwNumBytes是没有意义的。

再者,必须在pOverlapped参数总传入一个已初始化的OVERLAPPED结构。该结构定义如下:

typedef struct _OVERLAPPED  

{  

       DWORD Internal;//错误代码。  
       DWORD InternalHigh;//已传输字节数。  
       DWORD Offset;//低32位文件偏移。  
       DWORD OffsetHigh;//高32位文件偏移。  

       HANDLE hEvent;//事件对象句柄。  

}OVERLAPPED,*LPOVERLAPPED;  

---Offset,OffsetHigh,hEvent必须在调用ReadFile和WriteFile前初始化。

---Internal和InternalHigh由驱动程序设置。

---Offset和OffsetHigh共同构成一个64位的偏移量。它表示在访问文件时应该从何处访问设备。

提供偏移量是因为:在执行异步操作时系统会忽略文件指针。如果不再此处指定,那么系统将无法知道下次应该从哪里开始读取数据。为了防止在同一个对象上进行多个异步调用时出现混淆,所有的异步调用IO请求都必须在OVERLAPPED结构中指定起始偏移量。

非文件设备必须为这两个成员都指定为0,否则IO请求将会失败。此时GetLastError返回ERROR_INVALID_PARAMETER。

---hEvent标识一个事件内核对象句柄。用来接收IO完成通知的4种方法(后面会有介绍)的最后一种:使用IO完成端口会使用到这个成员。

---Internal成员用来保存已处理的IO请求的错误码。一旦我们发出一个异步IO请求,设备驱动程序会立即将Internal设为STATUS_PENDING,表示没有错误,因为操作尚未开始。通过检查此值我们可以使用

HasOverlappedIoCompeleted宏检查异步IO请求是否已经完成。

该宏定义为:

#define HasOverlappedIoCompeleted(pOverlapped)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值