ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Windows编程-异步IO-1-

2021-01-24 03:01:40  阅读:215  来源: 互联网

标签:异步 OVERLAPPED 文件 Windows IO DWORD hFile


 

Windows编程-异步IO-1-

当我们读取一个文件时,一般情况下,线程是阻塞的,也就是当前线程在等待文件读取操作结束,也就是这个线程只用来读文件,等读完了再返回。这种方式叫做同步IO。

Windows在系统底层为用户实现了另一种高效的机制,叫做重叠I/O,又称作异步I/O。异步I/O操作提供了一种功能当用户读取文件的时候,读取文件函数会立马返回结果,不会阻塞线程,但是实际上文件并没有读取完,而是交给了系统底层自动去处理,这样文件的读取操作就不会阻塞线程,但是这引发了一个问题,如何才能知道文件读取完毕了呢?

可以理解为打开文件后,对文件进行的操作交给了另一个线程或者是系统底层去处理

异步IO注意事项

一旦一个句柄是以异步I/O的方式打开的,那么:

1 句柄变为可等待的对象,也就是说它具有了激发态和非激发态

2 文件指针失效,需要用overlapped结构体中的offset表示读取或者写入的位置

异步IO结构体

typedef struct _OVERLAPPED {
ULONG_PTR Internal;//异步IO操作状态
ULONG_PTR InternalHigh;//操作了多少个字节
union {//文件偏移
  struct {
    DWORD Offset;
    DWORD OffsetHigh;
  } DUMMYSTRUCTNAME;
  PVOID Pointer;
} DUMMYUNIONNAME;
HANDLE   hEvent; //事件对象
} OVERLAPPED, *LPOVERLAPPED;

 

异步IO流程

打开一个文件-CreateFile

HANDLE CreateFileA(
LPCSTR               lpFileName,
DWORD                 dwDesiredAccess,
DWORD                 dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD                 dwCreationDisposition,
DWORD                 dwFlagsAndAttributes,
HANDLE               hTemplateFile
);

这里的其他参数都随意,只是在倒数第二个参数的时候需要添加异步I/O的自己参数FILE_FLAG_OVERLAPPED

定义一个异步IO的结构体

typedef struct _OVERLAPPED {
ULONG_PTR Internal;//异步IO操作状态
ULONG_PTR InternalHigh;//操作了多少个字节
union {//文件偏移
  struct {
    DWORD Offset;
    DWORD OffsetHigh;
  } DUMMYSTRUCTNAME;
  PVOID Pointer;
} DUMMYUNIONNAME;
HANDLE   hEvent; //事件对象
} OVERLAPPED, *LPOVERLAPPED;

进行文件操作

这里假设是进行ReadFile读写文件

BOOL ReadFile(
HANDLE       hFile,//文件句柄
LPVOID       lpBuffer,//缓冲区
DWORD       nNumberOfBytesToRead,//要获取的最大字节数
LPDWORD     lpNumberOfBytesRead,//用于返回实际存储数据大小的指针,也就是说获得存入了多少数据的大小的指针返回。但是如果有异步IO存在,这里就没有需要置为NULL
LPOVERLAPPED lpOverlapped//如果使用FILE_FLAG_OVERLAPPED打开了hFile参数, 则需要指向OVERLAPPED结构的指针,否则可以为NULL。


);

不要等待异步IO操作

异步IO操作会立刻返回一个结果,但是这个结果并不是全部的结果,不能作为一个完成的依据

在需要的时候再等待异步IO操作

在进行异步IO的时候就会自动给文件句柄附加信号值,然后调用WaitForSingleObject来等待信息,也就是表明异步IO结束了。

获得最终结果-GetOverlappedResult

BOOL GetOverlappedResult(
HANDLE       hFile,   //句柄
LPOVERLAPPED lpOverlapped,//overlapped结构体指针
LPDWORD     lpNumberOfBytesTransferred//实际读写的数量
BOOL         bWait//是否等待异步IO执行结束,TRUE等待,false不等待
);

异步IO流程例子

 
 1 #include<Windows.h>
 2 #include<iostream>
 3 
 4 
 5 int main()
 6 {
 7     //1打开一个文件
 8     HANDLE hFile = CreateFile(L"E:\\Project_Sum\\Win_Project\\IO_TEST\\test.txt", GENERIC_READ,NULL,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
 9     
10     //2创建一个异步IO结构体
11     OVERLAPPED overlapped{ 0 };
12 
13     //3调用文件处理函数和异步IO结构体
14     CHAR buf[100] = { 0 };
15     ReadFile(hFile, buf, 100, NULL, &overlapped);
16 
17 
18     //4 end等待异步IO结束
19     WaitForSingleObject(hFile, -1);
20     DWORD Sum_Number;
21     //5 获取结果
22     GetOverlappedResult(hFile,&overlapped,&Sum_Number,TRUE);
23     printf("文件内容为:%s\n", buf);
24     printf("实际读写数量为%ld\n", Sum_Number);
25 
26     //6关闭句柄
27     CloseHandle(hFile);
28     return 0;
29 }
View Code

 

标签:异步,OVERLAPPED,文件,Windows,IO,DWORD,hFile
来源: https://www.cnblogs.com/Sna1lGo/p/14319879.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有