第10章 同步设备I/O和异步设备I/O(3)_I/O完成端口

10.5 接收I/O请求完成的通知

(1)I/O请求被加入设备驱动程序的队列,当请求完成以后,设备驱动也要负责通知我们I/O请求己经完成。

(2)可以用4种方法来接收I/O请求己经完成的通知


技术


特点


触发设备内核对象


①允许一个线程发出I/O请求,另一个线程对结果进行处理。

②当向一个设备同时发出多个I/O请求的时候,这种方法是不能用的,因为等待函数中等待的是同一个内核对象,只要任何一个I/O请求完成时都会被触发,却没办法区别是哪个请求的完成触发了内核对象。


触发事件内核对象


①允许一个线程发出I/O请求,另一个线程对结果进行处理。

②允许我们向一个设备同时发出多个I/O请求的时候。(因为每个请求都通过pOverlapped与一个事件相关联)


使用可警告I/O


①发出I/O请求的线程必须对结果进行处理,因为这是通过线程的APC队列来实现的,而APC队列是线程独有的。

②允许我们向一个设备同时发出多个I/O请求的时候。


使用I/O完成端口


①允许一个线程发出I/O请求,另一个线程对结果进行处理。

②允许我们向一个设备同时发出多个I/O请求的时候。

③这项技术具有高度的伸缩性和最佳的灵活性

10.5.1 通过触发设备内核对象来通知I/O处理己完成

(1)Read/WriteFile在将I/O请求添加到队列之前,会先将对象设为未触发状态。当设备驱动程序完成了请求之后,会将设备内核对象设为触发状态。

(2)使用这种方法不能达到异步调用的好处,因为发出请求以后,要立即等待请求的完成,这跟同步调用效果是一样的。

【示例代码】——在实际的代码中,用这种方式来获取通知,因为没能真正体现异步的好处,也不能处理多个I/O请求

//以异步方问访问hFile设备(传入参数FILE_FLAG_OVERLAPPED)
HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);
BYTE bBuffer[100];
OVERLAPPED  o = { 0 };
o.Offset = 345; //从第346个字节开始读取数据

BOOL bReadDone = ReadFile(hFile, bBuffer, 100, NULL, &o); //添加异步I/O请求
DWORD dwError = GetLastError();

//ReadFile异步调用会立即,返回值为FALSE,GetLastError为ERROR_IO_PENDING表示
//请求正在被处理
if (!bReadDone && (dwError == ERROR_IO_PENDING)){
    //I/O请求正在被异步处理,等待I/O请求完成的通知
    WaitForSingleObject(hFile, INFINITE); //等待的是设备内核对象!
    bReadDone = TRUE;
}

if (bReadDone){
    //读取完成后,数据被写入bBuffer,状态信息写入pOverlapped结构体中
    //o.Internal包含IO错误代码
    //o.InternalHigh包含己经传输的字节数
    //bBuffer包含读取到的数据
} else{
    //出现错误,可查看dwError以获得更多信息
}

【示例程序2】——用来说明设备内核对象不能处理多个IO请求

//以异步方问访问hFile设备(传入参数FILE_FLAG_OVERLAPPED)
HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);

//异步I/O读请求
BYTE bReadBuffer[10];
OVERLAPPED  oRead = { 0 };
oRead.Offset = 0;
ReadFile(hFile, bReadBuffer, 100, NULL, &o); //添加异步I/O读请求

//异步I/O写请求
BYTE bWriteBuffer[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
OVERLAPPED  oWrite = { 0 };
oWrite.Offset = 10;
WriteFile(hFile, bWriteBuffer,_countof(bWriteBuffer), NULL, &oWrite);

...
WaitForSingleObject(hFile, INFINITE); //hFile被触发可以是读操作完成或写完成。
//我们不知道为什么完成:读?写?或两者都是?

10.5.2 触发事件内核对象

(1)在每个I/O请求的OVERLAPPED结构体的hEvent创建一个用来监听该请求完成的事件对象。当一个异步I/O请求完成时,设备驱动程序会调用SetEvent来触发事件。

(2)驱动程序仍然会像从前一样,将设备对象也设为触发状态,因为己经有了可用的事件对象,所以可以通过SetFileCompletionNoticationModes(hFile,FILE_SKIP_SET_EVENT_ON_HANDLE)来告诉操作系统在操作完成时,不要触发文件对象。

(3)以下代码是故意那样设计的。实际应用中,可用一个循环来等待I/O请求完成。

【示例程序】——利用事件对象处理多个IO请求

//以异步方问访问hFile设备(传入参数FILE_FLAG_OVERLAPPED)
HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);

//异步I/O读请求
BYTE bReadBuffer[10];
OVERLAPPED  oRead = { 0 };
oRead.Offset = 0;
oRead.hEvent = CreateEvent(...); //创建一个监听读的事件对象
ReadFile(hFile, bReadBuffer, 100, NULL, &o); //添加异步I/O读请求

//异步I/O写请求
BYTE bWriteBuffer[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
OVERLAPPED  oWrite = { 0 };
oWrite.Offset = 10;
oWrite.hEvent = CreateEvent(...);//创建一个监听写的事件对象
WriteFile(hFile, bWriteBuffer, _countof(bWriteBuffer), NULL, &oWrite);

...
HANDLE h[2];
h[0] = oRead.hEvent;
h[1] = oWrite.hEvent;
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw-WAIT_OBJECT_0)
{
    case 0: break;//读完成
    case 1: break;//写完成
}
时间: 2024-10-11 13:49:50

第10章 同步设备I/O和异步设备I/O(3)_I/O完成端口的相关文章

第10章 同步设备I/O和异步设备I/O(2)_同步IO和异步IO基础

10.3 执行同步设备I/O (1)对设备读写操作的函数 ①ReadFile/WriteFile函数 参数 描述 hFile 文件句柄 pvBuffer 指向要接收文件数据的缓冲区或把缓冲区数据写入设备 nNumbytesToRead 要读取的字节数或写入的字节数 pdwNumBytes 实际读取的字节数或写入的字节数 pOverlapped 指向OVERLAPPED结构体. ①要进行同步读写时,该参数为NULL,同时打开设备的时候,标志不能指定为FILE_FLAG_OVERLAPPED. ②要

第10章 同步设备I/O和异步设备I/O(1)

10.1 打开和关闭设备 10.1.1 设备的定义——在Windows中可以与之进行通信的任何东西. (1)常见设备及用途 设备 用途 用来打开设备的函数 文件 永久存储任何数据 CreateFile(pszName为路径名或UNC路径名) 目录 属性和文件压缩的设置 同上,如果指定FILE_FLAG_BACKUP_SEMANTICS标志,将打开一个目录.可以改变目录的属性(如正常或隐藏等)和他们的时间戳 逻辑磁盘驱动器 格式化驱动器 CreateFile(pszName为\\.\x:)其中的x

《Linux4.0设备驱动开发详解》笔记--第九章:Linux设备驱动中的异步通知与同步I/O

在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问.因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似"中断"的异步通知所取代.异步通知类似于硬件上的"中断"概念,比较准确的称谓是"信号驱动的异步I/O". 9.1 异步通知的概念和作用 异步通知:一旦设备就绪,则主动通知应用程序,该应用程序无需查询设备状态 几种通知方式比较: 阻塞I/O :一直等待设备可访问后开始访问 非阻塞I/O:

微软 Windows 10 将支持 8 英寸以下 ARM 平板设备

2015 年 1 月 24 日,  9:32 下午 - 微软本周展示了 Windows 10 一系列新的改变,也包括首次公开展示的 Windows 10 手机版,但 ARM 平板并没有得到太多提及. 而且微软官方也确认驱动 ARM 平板的 Windows RT 操作系统将只有“特殊更新提供部分 Windows 10 功能”,意味着现有 Surface RT 和 Surface 2 和 Lumia 2550 用户可能享受不到 Windows 10 完整系统功能. 不过微软仍会支持 ARM 平板设备

JavaScript高级程序设计(第三版)学习笔记8、9、10章

第8章,BOM BOM的核心对象是window,具有双重角色,既是js访问浏览器的一个接口,又是ECMAScript规定的Global对象.因此,在全局作用域中声明的函数.变量都会变成window对象的属性和方法. 例: var age = 20; function sayAge(){ alert(this.age); } alert(window.age); //20 window.sayAge(); //20 定义全局变量与在window对象上直接定义属性区别:全局变量不能通过delete操

第10章 系统级I/O

第10章 系统级I/O 10.1 Unix I/O 一个Unix文件就是一个m个字节的序列:B0,B1,…,BK,…,Bm-1 Unix I/O:一种将设备优雅地映射为文件的方式,允许Unix内核引出一个简单.低级的应用接口,这使得所有的输入输出都能以一种统一且一致的方式来执行: 打开文件: 内核返回一个小的非负整数,叫做描述符. Unix外壳创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0).标准输出(描述符为1).标准错误(描述符为2). 改变当前文件位置: 对于每个打开的文件,

阅读8,9,10章

第8章 本章主要讲需求分析,那么需求分析都包括哪些方面? 答:1 写出系统的任务和特点 2 要实现的功能模块及其作用 3 系统结构图(用UML描述) 4 采用的数据库 5 开发运行环境 第9章 本章主要讲简介项目经理的要求与能力,那么项目经理的职责是什么? 答:1.确保项目目标实现,保证业主满意 这一项基本职责是检查和衡量项目经理管理成败.水平高低的基本标志. 2.制定项目阶段性目标和项目总体控制计划 项目总目标一经确定,项目经理的职责之一就是将总目标分解,划分出主要工作内容和工作量,确定项目阶

3.26日第六次作业,第10章质量,11章人力

3.26日 第六次作业,第10章质量,11章人力 1.质量管理基本原则   以实用为核心的多元要求.系统工程.职工参与管理.管理层和第一把手重视.保护消费者权益.面向国际市场. 2.质量管理的目标顾客满意度.预防胜于检查.各阶段内的过程.   质量管理既重视结果也重视过程   实施组织主动采纳的质量改进措施(如全面质量管理.持续改进等) 3.质量管理的主要活动有哪些项目的质量管理可以分解为质量策划.质量保证与质量控制三个过程.质量策划是指确定与项目相关的质量标准,并决定如何达到这些质量标准.质量

MySQL性能调优与架构设计——第10章 MySQL数据库Schema设计的性能优化

第10章 MySQL Server性能优化 前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的参数优化,存储引擎的相关参数设置建议将主要在下一章“常用存储引擎的优化”中进行说明. 10.1 MySQL 安装优化 选择合适的发行版本 1. 二进制发行版(包括RPM等包装好的特定二进制版本) 由于MySQL开源的特性,不仅仅MySQL AB提供了多个平