PoEdu培训 Windows班 第九课 Windows异步IO操作
文章类别: 培训笔记 0 评论

PoEdu培训 Windows班 第九课 Windows异步IO操作

文章类别: 培训笔记 0 评论

Windows IO异步操作

异步IO机制

当我们使用CreateFile打开大文件或者其他设备的时候
可能会造成阻塞
所以我们Windows设计了异步IO机制.

画一个简单的图来表示一下同步和异步:
Alt 同步异步

为什么会产生阻塞

我们都知道, Windows下每个程序都有一个进程
进程是我们程序运行起来后的空间, 它起到存储数据的作用
线程则是我们实际运行进行操作的单位, 它是用来工作的, 和CPU打交道
进程相当于工厂, 线程相当于工人.
工厂可以有多个工人, 这种情况我们称之为多线程
阻塞, 就是我们的工作线程由于忙而被等待了.

可以通过多线程达到异步的操作
也可以通过Windows API的设置来达到异步的操作

WindowsAPI实现异步

HANDLE hFile = CreateFile(TEXT("Test.txt"), 
    GENERIC_READ | GENERIC_WRITE, 
    FILE_SHARE_READ, 
    NULL, 
    OPEN_ALWAYS, 
    FILE_FLAG_OVERLAPPED,    // 重要属性 该属性表示异步操作设备
    NULL);

当我们的 CreateFile 以异步方式打开后, 它返回的 hFile 的读写操作也将变成异步

OVERLAPPED结构体

原型:

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;    // 保存我们请求的错误码
  ULONG_PTR InternalHigh;    // 保存我们传输成功的字节数
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;
    };
    PVOID  Pointer;
  };    // 64位的偏移量  一个低位  一个高位
  HANDLE    hEvent;    // 事件内核对象
} OVERLAPPED, *LPOVERLAPPED;

Internal

InternalHigh

Pointer

hEvent

简单示例

#include <Windows.h>
#include <tchar.h>

int main()
{
    HANDLE hFile = CreateFile(TEXT("Test.txt"),
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        OPEN_ALWAYS,
        FILE_FLAG_OVERLAPPED,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        return -1;

    OVERLAPPED overLapped = { 0 };
    overLapped.Offset = 100;    // 从100开始读

    BYTE bBuffer[MAXBYTE] = { 0 };
    BOOL bRet = ReadFile(hFile, 
            bBuffer, 
            MAXBYTE,
            NULL,
            &overLapped);
    DWORD dwRet = GetLastError();

    if (bRet && dwRet == ERROR_IO_PENDING)
    {
        // 请求发送成功
        // 可以搞一些其他事情.
        // ...
        WaitForSingleObject(hFile, INFINITE);    // 阻塞到请求完成
        // 演示用, 正式环境请不要使用此方法
    }

    CloseHandle(hFile);

    return 0;
}

未完待续...

如有错误,请提出指正!谢谢.

回复