• 异步读写(ReadFileEx和ReadFile)之overlapped


    #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 ");
    }
    }
    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(" ");
    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(" ");
    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;
    }

  • 相关阅读:
    PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建
    终于还是离开这家公司了
    【转载】看完这篇文章,我奶奶都懂了https的原理
    PostgreSQL 函数学习
    Python 工作中比较实用的一些第三方库
    Python 获取对象的属性和方法—dir 函数
    Python 学习之type 函数的用法
    python 异常处理的基本语法
    pdb调试程序
    随机设置爬虫头部headers 信息
  • 原文地址:https://www.cnblogs.com/L-Sunny/p/8389388.html
Copyright © 2020-2023  润新知