异步I/O(2)使用事件内核对象

进行异步I/O的四种方式
1. 使用设备内核对象使用设备内核对象
2. 使用事件内核对象
3. 可提醒I/O可提醒I/O
4. I/O完成端口I/O完成端口

在进行异步I/O操作的时候

HANDLE WINAPI CreateFile(
  _In_      LPCTSTR lpFileName,
  _In_      DWORD dwDesiredAccess,
  _In_      DWORD dwShareMode,
  _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  _In_      DWORD dwCreationDisposition,
  _In_      DWORD dwFlagsAndAttributes,
  _In_opt_  HANDLE hTemplateFile
);

//dwFlagsAndAttributes这个参数必须设为FILE_FLAG_OVERLAPPED

此时需要用到OVERLAPPED的结构体

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;
  ULONG_PTR InternalHigh;
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;
    };
    PVOID  Pointer;
  };
  HANDLE    hEvent;
} OVERLAPPED, *LPOVERLAPPED;

使用事件内核对象进行异步I/O操作时需要对该结构体的hEvent进行设置

OVERLAPPED oRead = { 0 };
oRead.hEvent = CreateEvent(nullptr, TRUE, FALSE, L"ReadEvent");
ReadFile(hFile, bReadBuf, 100, nullptr, &oRead);
HANDLE WINAPI CreateEvent(
  _In_opt_  LPSECURITY_ATTRIBUTES lpEventAttributes,
  //一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承

  _In_      BOOL bManualReset,
  //指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态

  _In_      BOOL bInitialState,
  //指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态

 _In_opt_  LPCTSTR lpName
  //指定事件的对象的名称
);

简单的事例

int main()
{
    HANDLE hFile = CreateFileW(L"demo.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, nullptr);

    if(hFile != INVALID_HANDLE_VALUE)
    {
        //Read
        BYTE bReadBuf[100] = { 0 };
        OVERLAPPED oRead = { 0 };
        oRead.hEvent = CreateEvent(nullptr, TRUE, FALSE, L"ReadEvent");
        ReadFile(hFile, bReadBuf, 100, nullptr, &oRead);

        //Write
        BYTE bWriteBuf[10] = { 0 };
        OVERLAPPED oWrite = { 0 };
        oWrite.hEvent = CreateEvent(nullptr, TRUE, FALSE, L"WriteEvent");
        WriteFile(hFile, bWriteBuf, 10, nullptr, &oWrite);

        //do something

        HANDLE hOverLapped[2] = { 0 };
        hOverLapped[0] = oRead.hEvent;
        hOverLapped[1] = oWrite.hEvent;

        while (true)
        {
            DWORD dwCase = WaitForMultipleObjects(2, hOverLapped, FALSE, INFINITE);
            switch (dwCase - WAIT_OBJECT_0)
            {
            case 0:
                //read
                MessageBox(nullptr, L"Read", L"Read", MB_OK);
                break;
            case 1:
                //write
                MessageBox(nullptr, L"Write", L"Write", MB_OK);
                break;
            default: break;
            }
        }
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值