首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重叠I/O的GetOverlappedResult(bWait=TRUE)与WaitForSingleObject()

重叠I/O的GetOverlappedResult(bWait=TRUE)与WaitForSingleObject()
EN

Stack Overflow用户
提问于 2017-03-11 23:46:09
回答 2查看 2.9K关注 0票数 5

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

  • WaitForSingleObject
  • GetOverlappedResult与bWait=TRUE

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

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

EN

回答 2

Stack Overflow用户

发布于 2017-03-12 01:15:49

我完全同意Rusanu 回答。另外,创建自己的IOCP和线程池,它们将侦听此IOCP,您可以使用或BindIoCompletionCallbackCreateThreadpoolIo (从vista开始)--在本例中,系统自己创建IOCP,线程池将侦听此IOCP,当某些操作完成时,调用回调。这是非常简单的代码相对于自己的iocp/线程池(确实是自己的iocp/线程池,我认为只有当您有非常大的I/O (例如服务器端的socket io )并且需要进行特殊的优化时才有意义的实现)

然而,

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

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

  • 如果操作完成,请返回NumberOfBytesTransferred。
  • 如果操作完成时出现错误NTSTATUS -将其转换为win32错误并设置最后一个错误
  • 如果操作仍然挂起,并且需要等待,则选择hFile或hEvent上的等待。

所以GetOverlappedResult[Ex]所做的不仅仅是简单的调用WaitForSingleObject

然而,并不是很难自己实现这个API。例如

代码语言:javascript
复制
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]还是自己实现它呢?

票数 4
EN

Stack Overflow用户

发布于 2017-03-11 23:54:09

你可以使用这两种方法,但这确实不是正确的方法。应该将句柄附加到IO完成端口,然后在完成端口上等待。这样,您就有一个线程池为多个IO事件服务,因为您可以将多个句柄附加到一个完成端口。我建议阅读高性能应用程序的设计

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42742036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档