重叠I/O的GetOverlappedResult(bWait=TRUE)与WaitForSingleObject()
当我在Win32 api上以重叠方式打开和读取文件时,我有几种方法来完成IO请求,包括使用等待文件句柄(或重叠结构中的事件)重叠I/O的GetOverlappedResult(bWait=TRUE)与WaitForSingleObject(),c,windows,winapi,C,Windows,Winapi,当我在Win32 api上以重叠方式打开和读取文件时,我有几种方法来完成IO请求,包括使用等待文件句柄(或重叠结构中的事件) WaitForSingleObject GetOverlappedResult,bWait=TRUE 这两个函数似乎具有相同的效果:线程在句柄或事件发出信号之前停止,这意味着数据被放置在提供给ReadFile的缓冲区中 那么,有什么区别呢?为什么我需要GetOverlappedResult?您可以使用这两种方法,但这确实不是“正确”的方法。您应该将句柄连接到IO完成端
WaitForSingleObject
,bWait=TRUEGetOverlappedResult
ReadFile
的缓冲区中
那么,有什么区别呢?为什么我需要
GetOverlappedResult
?您可以使用这两种方法,但这确实不是“正确”的方法。您应该将句柄连接到IO完成端口,然后等待完成端口。这样,您就有了一个线程池来为许多IO事件提供服务,因为您可以将多个句柄附加到一个完成端口。我推荐阅读。我完全同意雷姆斯·鲁萨努的观点。此外,还可以创建自己的IOCP和线程池,它们将在此IOCP上侦听,您可以使用or或(从vista开始)-在这种情况下,系统自己创建IOCP和线程池,它将在此IOCP上侦听,当某些操作完成时-调用您的回调。这是非常简单的代码与自己的iocp/线程池(我认为自己的iocp/线程池只有在拥有大量i/O(比如服务器端的套接字io)并且需要针对性能进行特殊优化时才有意义地实现)
然而
那么,有什么区别呢?为什么我需要GetOverlappedResult
如何查看GetOverlappedResult[Ex]
不仅等待结果,而且
- 如果操作完成,则返回NumberOfByTestTransferred
- 如果操作已完成,但出现错误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]
或者自己实现它的功能?谢谢,但我的I/O操作不会超过2个,所以我不确定我是否需要IO完成端口。我知道它们和其他方法,如可变IO(APC)。我的问题是关于区别:)@user996142使用IO完成端口总是比使用GetOverlappedResult
等待要好。对于I/O操作的任何计数,您也可以通过或@RbMm间接使用它。在一般情况下,我100%同意IOCP将优于重叠IO。我所知道的一个例外是全双工串行IO。根据“阅读和写作”一节中的“非重叠IO”小节,注意,如果不使用重叠IO,串行端口上不可能进行全双工通信。@dgnuff-IOCP将优于重叠IO-重叠I/O-这是异步I/O。这意味着文件句柄在异步模式下打开-带有标志file\u flag\u overlapped
(如果我们使用CreateFile
)或者如果我们使用ZWAPI,则没有文件\u同步\u IO\u[NON]警报
标志。IOCP
只能在文件句柄为的情况下与之关联(查看1550行)。所以你的评论是不正确的。IOCP不是io类型。这是另一个问题。并且只能与重叠的IOShort版本一起使用:WaitForSingleObject
不会告诉您操作是成功还是失败,如果它碰巧是一种I/O,可能处理的字节数比您要求的要少,您也不会知道。