同步异步设备IO1.doc

上传人:M****1 文档编号:558560808 上传时间:2023-08-06 格式:DOC 页数:8 大小:68KB
返回 下载 相关 举报
同步异步设备IO1.doc_第1页
第1页 / 共8页
同步异步设备IO1.doc_第2页
第2页 / 共8页
同步异步设备IO1.doc_第3页
第3页 / 共8页
同步异步设备IO1.doc_第4页
第4页 / 共8页
同步异步设备IO1.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《同步异步设备IO1.doc》由会员分享,可在线阅读,更多相关《同步异步设备IO1.doc(8页珍藏版)》请在金锄头文库上搜索。

1、设备I/O的同步与异步一、 概述Windows的优势之一是它支持大量的设备类型,这里我们将设备笼统的定义为能够与之通信的任何东西,常见的一些设备及打开方式有:设备打开设备的函数文件CreateFile()目录同上逻辑磁盘驱动器同上物理磁盘驱动器同上串口同上并口同上邮件槽服务器CreateMailslot()邮件槽客户端CreateFile()命名管道服务器CreateNamedPipe()命名管道客户端CreateFile()匿名管道CreatePipe()套接字Socket()控制台CreateConsoleScreenBuffer() CreateStdHandle()当然,这里只是简单地

2、列出了各个设备打开的API,具体用法参数可以查阅MSDN或者SDK。当线程与设备发生通信时,即线程发出设备I/O请求时,一般来说有两种方式:同步设备I/O请求:字如其名,线程发出设备I/O请求后,它会被临时挂起,直到设备完成I/O请求为止,显然这种方式严重损坏性能;异步设备I/O请求:线程发出设备I/O请求后,不会被临时挂起而是继续执行其他任务,而设备同时继续处理I/O请求,设备处理完成后发送信号给线程,线程接着处理I/O结果。异步设备I/O可以避免线程挂起导致的CPU大量闲置,提高了利用率和吞吐量。与设备I/O的通信交互是Windows编程中的重点,涉及到诸多的线程的同步方式,尤其是I/O完

3、成端口的引入,使得不管是否与设备I/O关联,都提供了一种有无数种用途的绝佳的线程间通信机制。囿于学力,很多部分的理解都很有限,把自己掌握的整理出来,以便日后再学习吧。这篇笔记的结构大致如下: 打开和关闭设备 使用文件设备 异步设备I/O基础 接收I/O请求完成通知二、 打开和关闭设备为了执行任何类型的设备I/O,我们必须先打开想要操作的设备并得到一个句柄,随后我们可以讲该句柄传给许多函数来与设备进行通信。这里同样用这个设备句柄来唯一标识我们的设备。HANDLE CreateFile(PCTSTR pszName,DWORD dwDesiredAccess,DWORD dwShareMode,P

4、SECURITY_ATTRIBUTES psa,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hFileTemplate);从之前的表中也可以看出,CreateFile是打开许多设备句柄的关键函数,所以我们对它的参数做一个具体的说明。l pszName:既可以标识设备的类型,也可以表示该类设备的某个实例。l dwDesiredAccess:用来指定我们相用什么样的方式来和设备进行数据传输,常见的有四个标志,它们是0表示我们不希望对设备读出或写入任何数据,一般用来只想改变设备的配置(比如修改文件的时间戳)GENERIC

5、_READ允许对设备进行只读访问GENERIC_WRITE允许对设备进行只写访问,比如备份软件或者将数据发送到打印机GENERIC_READ | GENERIC_WRITE允许对设备进行读写操作l dwShareMode:用来指定设备共享特权(device-sharing privilege),但我们打开一个设备但是尚未调用CloseHandle()关闭时,该参数可以控制其他的CreateFile()调用以何种方式打开设备。常见参数有0要求独占对设备的访问FILE_SHARE_READ只允许共享设备读取方式FILE_SHARE_WRITE只允许共享设备写入方式FILE_SHARE_READ |

6、 FILE_SHARE_WRITE不解释FILE_SHARE_DELETE对文件操作时我们不关心文件是否被逻辑删除或者被移动,先将文件打上待删除标记,只有当该文件打开的所有句柄都被关闭的时候再将其真正删除l Psa指向一个内核对象都具备的安全属性结构,里面可以指定安全信息以及我们是否希望CreateFile返回的句柄能被继承。通常我们传入NULL,这表示用默认的安全设定来创建文件,并且返回的句柄是不可继承的。l dwCreationDisposition:用来表示用CreateFile打开文件时如果碰到存在的同名文件等情况如何处理,如CREATE_NEW若存在同名文件,则调用失败CREATE_

7、ALWAYS若存在同名文件,则覆盖OPEN_EXISTING若打开的文件或者设备不存咋则调用失败OPEN_ALWAYS若打开文件不存在则只直接创建一个当调用CreateFile打开文件之外的其他设备时,必须将OPEN_EXISTING传给dwCreationDisposition参数l dwFlagsAndAttributes:允许我们设置一些标志来微调与设备之间的通信;其次我们还可以通过一些属性参数来设置文件属性。比如常见的告诉缓存标志:FILE_FLAG_NO_BUFFERING告诉高速缓存管理器我们不希望它对任何数据进行缓存,我们会自己对数据进行缓存;标志FILE_FLAG_DELETE

8、_ON_CLOSE可以让文件系统在文件的所有句柄都被关闭后删除该文件(比如程序运行用到的临时文件,结束后删除,更加隐蔽),标志FLIE_FLAG_BACKUP_SEMANTICS用于备份和恢复软件,不要求文件的全部管理员权限,还有一个重要的标志FILE_FLAG_OVERLAPPED告诉系统我们想要以异步方式来访问设备,默认是同步I/O访问请求。我们重点来介绍一下文件属性参数,可以看到常见的Windows文件属性都有涉及FILE_ATTRIBUTE_ARCHIVE存档文件,默认自动设置FILE_ATTRIBUTE_ENCRYPTED加密文件FILE_ATTRIBUTE_HIDDEN隐藏文件FI

9、LE_ATTRIBUTE_NORMAL没有其他属性,只有单独使用时才有效FILE_ATTRIBUTE_SYSTEM系统文件FILE_ATTRIBUTE_READONLY只读文件OK,可以看到右键文件属性的所有可能这里基本都有涉及,尽管没有向Linux那样提供了丰富的命令行选项,但是Windows在API参数中也为我们提供了尽可能多的功能选项。三、 使用文件设备文件的使用非常普遍,因此重点来讨论下与文件设备有关的问题。首先我们看看如何取得文件的大小。BOOL GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER pliFileSize /联合类型指针);hFil

10、e当然就是目标文件的句柄了,pliFileSize是一个LARGE_INTEGER联合类型的地址,这个联合体允许我们以一个64位的有符号数的形式来引用一个64位有符号数,或者以两个32位值的形式来引用一个64位有符号数。下面是大概的定义:Typedef union _LARGE_INTEGER Struct DWORD LowPart; /Low 32-bit unsigned value LONG HighPart; /High 32-bit signed value; LONGLONG QuadPart; /Full 64-bit signed value LARGE_INTEGER, *

11、PLARGE_INTEGER;我们调用GetFileSizeEx可以得到文件的逻辑大小,使用GetCompressedFileSize可以得到文件压缩后的物理大小。如果要对一个文件读写,其实就是向文件发送一个I/O请求,当然,这里的道理其实不仅适用于文件,对于设备同样适用,如邮件槽、管道、套接字等等。我们通常使用如下函数发送I/O请求,BOOL ReadFile( HANDLE hFile, PVOID pvBuffer, DWORD nNumBytesToRead, PDWORD pdwNumBytes, OVERLAPPED* pOverlapped);BOOL WriteFile( HA

12、NDLE hFile, CONST VOID *pvBuffer, DWORD nNumBytesToWrite, PDWORD pdwNumBytes, OVERLAPPED* pOverlapped);执行同步I/O时pOverlapped设为NULL,只有在异步I/O时才有意义。每当调用CreateFile时系统会创建一个文件内核对象来管理对文件的操作,在这个内核对象中维护这一个文件指针,它指向一个64位的偏移量,表示应该在哪里执行下一次同步读取或写入操作,我们称之为文件指针,初始化为0。需要注意的是,调用CreateFile打开同一个文件会得到多个文件内核对象,内部维护的文件指针彼此独

13、立。我们可以使用SetFilePointerEx来设置文件指针的位置BOOL SetFilePointerEx( HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLAGER_INTEGER pliNewFilePointer, DWORD dwMoveMethod);hFile表示我们想要修改哪个文件内核对象的文件指针。liDistanceToMove告诉系统我们想要移动把指针在dwMoveMethod指定的位置移动多少个字节。使用负数可以将文件指针向后移动。dwMoveMehtod告诉系统如何解释liDistanceToMove,比如常用的参数值

14、为FILE_BEGIN从文件头开始计算liDistanceToMove,之和为当前的文件指针FILE_CURRENT从当前的文件指针位置开始计算FILE_END在文件末尾开始计算我们给出一个小例子/本程序用来实验联系Windows关于文件读写操作的API/命令行启动,参数作为写入文件的内容#include #include #include #include using namespace std;int main(int argc, char *argv)/操作一个文件之前必须先调用CreateFile()函数以指定的方式打开一个文件/访问方式:GENERIC_READ |GENERIC_WRITE/共享模式:当文件被打开时,其他程序可以对该文进进行的操作,表示不允许同时对任何操作/创建方式:当文件存在或者不存在时的处理策略CREATE_ALWAYS, CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING/新创建的文件属性:ARCHIVE(存档),HIDDEN, SYSTEM, READONLY/模板文件:没有则设为NULLHANDLE hFile;hFile = CreateFile(LC:Documents and Settingsadmin桌面FileAPITest.txt, GENERIC_WRITE,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号