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

来源:互联网 发布:现代德军 淘宝 编辑:程序博客网 时间:2024/05/16 10:13

进行异步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;}
原创粉丝点击