当我在Win32 api上以重叠方式打开和读取文件时,我有几种方法来完成IO请求,包括等待文件句柄(或重叠结构中的事件)
WaitForSingleObjectGetOverlappedResult与bWait=TRUE这两个函数似乎具有相同的效果:线程停止直到句柄或事件被发出信号,这意味着数据被放置在提供给ReadFile的缓冲区中。
那么,有什么区别呢?为什么我需要GetOverlappedResult
发布于 2017-03-12 01:15:49
我完全同意Rusanu 回答。另外,创建自己的IOCP和线程池,它们将侦听此IOCP,您可以使用或BindIoCompletionCallback或CreateThreadpoolIo (从vista开始)--在本例中,系统自己创建IOCP,线程池将侦听此IOCP,当某些操作完成时,调用回调。这是非常简单的代码相对于自己的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]还是自己实现它呢?
发布于 2017-03-11 23:54:09
你可以使用这两种方法,但这确实不是正确的方法。应该将句柄附加到IO完成端口,然后在完成端口上等待。这样,您就有一个线程池为多个IO事件服务,因为您可以将多个句柄附加到一个完成端口。我建议阅读高性能应用程序的设计。
https://stackoverflow.com/questions/42742036
复制相似问题