当我在 Win32 api 上以 OVERLAPPED 方式打开和读取文件时,我有几种方法来完成 IO 请求,包括等待文件句柄(或重叠结构中的事件)使用

  • WaitForSingleObject
  • GetOverlappedResult with bWait=TRUE

  • 这两个函数似乎具有相同的效果:线程停止,直到发出句柄或事件信号,这意味着数据被放置在提供给 ReadFile 的缓冲区中。

    那么区别是什么呢?为什么我需要 GetOverlappedResult

    最佳答案

    我完全同意 Remus Rusanu answer 。也可以创建自己的 IOCP 和线程池,它们将监听此 IOCP,您可以使用 BindIoCompletionCallback CreateThreadpoolIo (从 vista 开始)-在这种情况下,系统自己创建 IOCP 和线程池,它将监听此 IOCP,当某些操作完成 - 调用您的回调。与自己的 iocp/线程池相比,这是非常简化的代码(我认为只有当您有非常大的 I/O 计数(比如服务器端的套接字 io)并且需要对性能进行特殊优化时,才可以使用自己的 iocp/线程池)

    然而



    你如何看到 GetOverlappedResult[Ex] 不仅等待结果,而且

    如果操作完成,

  • 返回给您 NumberOfBytesTransferred。
  • 如果操作完成并出现错误 NTSTATUS - 将其转换为 win32
    错误并设置最后一个错误
  • 如果操作仍然挂起并且您想要等待 - 它选择等待
    hFile 或 hEvent

  • 所以 GetOverlappedResult[Ex] 不仅仅是简单地调用 WaitForSingleObject
    但是自己实现这个 API 并不难。例如
    BOOL
    WINAPI
    MyGetOverlappedResult(
                        _In_ HANDLE hFile,
                        _In_ LPOVERLAPPED lpOverlapped,
                        _Out_ LPDWORD lpNumberOfBytesTransferred,
                        _In_ BOOL bWait
                        )
    {
        if ((NTSTATUS)lpOverlapped->Internal == STATUS_PENDING)
        {
            if (!bWait)
            {
                SetLastError(ERROR_IO_INCOMPLETE);
                return FALSE;
            }
    
            if (lpOverlapped->hEvent)
            {
                hFile = lpOverlapped->hEvent;
            }
    
            if (WaitForSingleObject(hFile, INFINITE) != WAIT_OBJECT_0)
            {
                return FALSE;
            }
        }
        else
        {
            MemoryBarrier();
        }
    
        *lpNumberOfBytesTransferred = (ULONG)lpOverlapped->InternalHigh;
        NTSTATUS status = (NTSTATUS)lpOverlapped->Internal;
        if (status)
        {
            RtlNtStatusToDosError(status);
        }
        return NT_SUCCESS(status);
    }
    

    那么有什么更好的:使用 GetOverlappedResult[Ex] 或自己实现它的功能?

    关于c - 重叠 I/O 的 GetOverlappedResult(bWait=TRUE) 与 WaitForSingleObject(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42742036/

    10-15 06:44