当我在 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]
不仅等待结果,而且
如果操作完成,
错误并设置最后一个错误
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/