当我在Win32 api上以OVERLAPPED方式打开并读取文件时,我有几种方法可以完成IO请求,包括使用
等待文件句柄(或重叠结构中的事件)WaitForSingleObject
GetOverlappedResult
,bWait = TRUE 两个函数似乎都有相同的效果:线程停止直到句柄或事件发出信号,这意味着数据被放在提供给ReadFile
的缓冲区中。
那么,有什么区别?为什么我需要GetOverlappedResult
?
答案 0 :(得分:3)
我完全同意 Remus Rusanu answer。而是创建自己的 IOCP 和线程池,它将在此 IOCP 上侦听,您可以使用或BindIoCompletionCallback
或CreateThreadpoolIo
(从vista开始) ) - 在这种情况下,系统自己创建 IOCP 和线程池,它将监听此 IOCP ,当某些操作完成时 - 调用您的回调。这是非常简化的代码vs自己的iocp /线程池(自己的iocp /线程池真的我认为只有当你有非常大的计数I / O(比如服务器端的socket io)并且需要特殊的性能优化时才有意义实现)
然而
那么,有什么区别?为什么我需要GetOverlappedResult
您如何看待GetOverlappedResult[Ex]
不仅等待结果,还
所以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]
或自己实现功能吗?
答案 1 :(得分:2)
你可以使用其中任何一种,但真的不是“正确的”#39;这样做的方式。您应该将句柄附加到IO完成端口,然后等待完成端口。这样,您就有一个服务于许多IO事件的线程池,因为您可以将多个句柄附加到完成端口。我建议阅读Designing Applications for High Performance。