《Windows Via C/C++》学习之同步设备I/O与异步设备I/O

这章可就讲设备了。好好想想,其实一个有用的程序都得和设备打交道,这章是相当的重要。可惜我看得不是很透。

和设备打交道的方法分为同步和异步。同步就是我调用了函数说要读100个字符后,就站那等着,等到100个字符全读完了再继续往前走。异步就是我调用了函数后,让驱动程序自己读取,我不理他直接接着往前走,直到某个点必须要用那100个字符了,再开始等。

1.    先说使用设备的方法。常见的设备有文件、串口、并口、控制台、命名管道、匿名管道、套接字、邮件槽等等。使用设备的时候都要用到设备内核对象。通常的设备都用CreateFile函数来创建内核对象。注意,CreateFile函数有一个参数很重要,dwFlagsAndAttributes,当给这个参数传FILE_FLAG_OVERLAPPED标志时就表示以异步方式打开设备,如果不传该标志,就是默认的同步方式。关闭设备内核对象句柄的方式还是CloseHandle。作为一个特例,本书专门讲了文件设备的使用方法。只不过使一些函数而已,不细说了。

2.    下面开始将同步设备I/O。为了使用同步I/O,在创建设备内核对象时CreateFile函数不应传入FILE_FLAG_OVERLAPPED。读同步设备的函数是ReadFile,写设备的函数是WriteFile(其实异步方式也是这两个函数)。因为是同步方式,所以两个函数的OVERLAPPED* 参数处应传NULL。同步方式的缺陷是,由于等待同步I/O操作会导致线程被挂起。即在执行ReadFile或者CreateFile的时候会被挂起。

3.    异步设备I/O。为使用异步I/O,创建设备内核对象时CreateFile必须传入FILE_FLAG_OVERLAPPED。读或写异步设备的函数依然是ReadFile和WriteFile,不过两个函数必须传入OVERLAPPED* 参数。注意,正是ReadFile和WriteFile函数把异步设备I/O请求加入设备驱动程序的队列中,然后线程才得以继续执行下去。
在I/O请求完成的时候,驱动程序会通知我们的线程。通知的方式有4种。
第一种,触发设备内核对象。即在I/O请求进队前,ReadFile或WriteFile先将设备内核对象设为未触发状态,I/O请求完成后,驱动程序将其设为触发状态。这种方法显然的缺陷是,当向一个设备同时发出多个I/O请求时,无法判断到底是哪个完成完成了。
第二种,触发事件内核对象。这就利用了OVERLAPPED结构中的hEvent分量。其实原理同第一种方式(把设备内核对象换成事件内核对象)。他可以解决第一种方式的缺陷,即为每个请求创建不同的事件对象。
第三种,使用可提醒I/O。这个主要是利用了线程的APC队列。书上说这种方法太次,可以无视之。
第四种,使用I/O完成端口。作者竭力推荐的方法。这种方法可以解决第一种方式的缺陷。(怎么解决的?我的理解是使用GetQueuedCompletionStatus取得的OVERLAPPED ** 所附带的信息)

4.    I/O完成端口。其设计初衷是与线程池配合使用,因此理解的时候可以从那个角度出发。一个线程最多可以与一个完成端口关联。废话就不说了,使用方法:

创建I/O完成端口(CreateIoCompletionPort)
|
将设备与I/O完成端口关联(亦CreateIoCompletionPort,这里设置了完成键)
|
ReadFile或者WriteFile产生I/O请求(异步的)
|
等待和获取当前I/O完成端口上完成的I/O请求(GetQueuedCompletionStatus)
|
根据上一步取得的完成键和OVERLAPPED等信息作出相应处理

文章转载自: http://hi.baidu.com/dsa343/blog/item/1605ebcb479403f453664f5c.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值