博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异步读写(ReadFileEx和ReadFile)之overlapped
阅读量:7114 次
发布时间:2019-06-28

本文共 3758 字,大约阅读时间需要 12 分钟。

 

#include "stdafx.h"

#include <windows.h>
#include <iostream>

using namespace std;

#define PAGE_SIZE 0x1000

void Sub_1(); //ReadFile 异步操作
void Sub_2(); //ReadFileEx
DWORD WINAPI Sub_1ThreadProcedure(LPVOID ParameterData);
DWORD WINAPI Sub_2ThreadProcedure(LPVOID ParameterData);
OVERLAPPED __Overlapped = { 0 };
char __BufferData[4] = {0};

int main()

{

Sub_1();

//Sub_2();
}
void Sub_1()
{
BOOL IsOk = FALSE;
DWORD ReturnLength = 0;
HANDLE FileHandle = CreateFile(L"ReadMe.txt", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);//FILE_FLAG_OVERLAPPED很重要在异步
//有FILE_FLAG_OVERLAPPED系统就已经默认OverLapped了如果要同步必须删除
if (FileHandle == INVALID_HANDLE_VALUE)
{
int LastError = GetLastError();
goto Exit;
}

__Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //绝对要创建 IRP那里看

if (__BufferData == NULL)

{
goto Exit;
}
IsOk = ReadFile(FileHandle, __BufferData, 4, &ReturnLength, &__Overlapped); //这里是通知IO要进行异步__Overlapped
//接下来返回到线程,所以有Wait那一步,线程才会去执行 线程和当前进程无关
if (IsOk == FALSE)
{
int LastError = GetLastError();

if (LastError == ERROR_IO_PENDING)
{
printf("ERROR_IO_PENDING\r\n");
}
}
HANDLE ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Sub_1ThreadProcedure,
(LPVOID)FileHandle, 0, NULL);

WaitForSingleObject(ThreadHandle, INFINITE);

Exit:
if (FileHandle != NULL)
{
CloseHandle(FileHandle);
FileHandle = NULL;
}
printf("\r\n");
return;
}
DWORD WINAPI Sub_1ThreadProcedure(LPVOID ParameterData)
{
HANDLE FileHandle = (HANDLE)ParameterData;
BOOL IsOk = FALSE;
DWORD ReturnLength = 0;
while (1)
{
IsOk = WaitForSingleObject(__Overlapped.hEvent, INFINITE);
IsOk -= WAIT_OBJECT_0;
if (IsOk == 0)
{
IsOk = GetOverlappedResult(FileHandle, &__Overlapped, &ReturnLength, INFINITE);//ReturnLength读了多少字节

if (IsOk==TRUE)

{
int i = 0;
for (i = 0; i < ReturnLength; i++)
{
printf("%c", __BufferData[i]);
}
__Overlapped.Offset += ReturnLength;//这里是每次读写的起始位置,所以要加下去
ReadFile(FileHandle, &__BufferData, 4, &ReturnLength, &__Overlapped);
}
else
{
//数据完毕
break;
}
}
else
{
return 0;
}
}

return 0;

}

void Sub_2()

{
BOOL IsOk = FALSE;
HANDLE FileHandle = CreateFile(L"ReadMe.txt", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (FileHandle == INVALID_HANDLE_VALUE)
{
int LastError = GetLastError();
goto Exit;
}

//__Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //绝对不能提供该事件
HANDLE ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Sub_2ThreadProcedure,
(LPVOID)FileHandle, 0, NULL);

if (__BufferData == NULL)

{
goto Exit;
}
IsOk = ReadFileEx(FileHandle, __BufferData, 4, &__Overlapped, NULL);
if (IsOk == FALSE)
{
int LastError = GetLastError();

if (LastError == ERROR_IO_PENDING)

{
//成功
}
}
WaitForSingleObject(ThreadHandle, INFINITE);
Exit:
if (FileHandle != NULL)
{
CloseHandle(FileHandle);
FileHandle = NULL;
}
printf("\r\n");
return;
}

DWORD WINAPI Sub_2ThreadProcedure(LPVOID ParameterData)

{
HANDLE FileHandle = (HANDLE)ParameterData;
DWORD ReturnLength = 0;
BOOL IsOk = FALSE;
while (1)
{
/*如果函数调用返回FALSE则可以用GetLastError来得到错误,如果返回成功则可以通过
lpNumberOfBytesTransferred参数来确定当前有多少数据已经被读或写。lpOverlapped
参数必须与调用ReadFile或WriteFile时使用同一个数据区。最后一个参数bWait表明是
否等待异步操作结束时才返回,如果设置为TRUE就可以等待文件读写完成时返回,
否则就会马上返回,利用这个特点可以利用它来等待异步文件操作的结束
(就如同等待事件变为有信号状态一样起到相同的作用)。
*/
IsOk = GetOverlappedResult(FileHandle, &__Overlapped, &ReturnLength, TRUE);
//IsOk = WaitForSingleObject(__Overlapped.hEvent, INFINITE); //?? 绝对不能这样做
if (IsOk == TRUE)
{
int i = 0;
for (i = 0; i < ReturnLength; i++)
{
printf("%c", __BufferData[i]);
}

__Overlapped.Offset += ReturnLength;

ReadFileEx(FileHandle, &__BufferData, 4, &__Overlapped, NULL);
}
else
{
return 0;
}
}

return 0;

}

 

转载于:https://www.cnblogs.com/L-Sunny/p/8389388.html

你可能感兴趣的文章
RxJS Observable - 一个奇特的函数
查看>>
大型WEB架构设计
查看>>
小程序TAB列表切换内容动态变化,scrollview高度根据内容动态获取
查看>>
swoole_table 实现原理剖析
查看>>
你需要知道面试中的10个JavaScript概念
查看>>
TiDB RC4 Release
查看>>
阿里云有对手了!CDN横评:腾讯云优势明显
查看>>
Ajax常用方法
查看>>
Glide 简单流程分析
查看>>
Hmily 2.0.3 发布,高性能异步分布式事务 TCC 框架
查看>>
烟花年下岁月
查看>>
Java源码阅读之HashMap - JDK1.8
查看>>
JavaScript 工厂模式和订阅模式
查看>>
阮一峰老师微博上的关于js作用域的一道题
查看>>
关于两个程序员的寓言故事
查看>>
Docker 构建统一的前端开发环境
查看>>
一文让你了解大数据时代,你的真实处境
查看>>
Problems at works
查看>>
Dell服务器系统安装后无法正常进入系统
查看>>
深入理解asp.net里的HttpModule机制
查看>>