4

我目前正在使用 IO 完成端口研究基于命名管道的 IPC 机制。

不幸的是,我在使用 msdn 文档时遇到了一些问题,因为我不清楚在哪些情况下调用 ReadFile/WriteFile 会导致完成数据包。

ERROR_IO_PENDING 返回 FALSE 的情况很清楚,但是当 ERROR_MORE_DATA 返回时显然可能的情况呢?这种情况下会有完成包吗?此外,如果返回其他错误怎么办?在哪些情况下我必须直接而不是在完成处理程序中处理结果和释放资源?

另一种情况是如果 ReadFile/WriteFile 甚至成功,这显然也是可能的。谢天谢地, MSDN 对此非常清楚:

此外,WriteFile 函数有时会返回 TRUE,GetLastError 值为 ERROR_SUCCESS,即使它使用异步句柄(也可以返回 FALSE 和 ERROR_IO_PENDING)。...在此示例中,建议允许完成端口例程单独负责此类资源的所有释放操作。

这个建议是否在所有情况下都是正确的,并且分配给完成端口的句柄的 ReadFile/WriteFile 操作的结果实际上可以(并且应该)被完全忽略,因为无论如何都会将数据包发送到端口?

4

2 回答 2

3

只要 IO 操作能够开始,就会有一个 IO 完成项排队等待 IO 操作。无论IO操作开始后是否遇到错误,都会有一个完成项排队到完成端口。

IO 系统返回的代码和 Win32 错误代码之间存在映射问题,NTSTATUS这使得很难区分哪些状态是错误,哪些只是信息。NTSTATUS由内核和本机 API 使用,有四个严重级别:成功、信息、警告和错误。除了错误代码之外的任何内容都表明 IO 操作能够开始。Win32 只有一种严重性 ( ERROR_*),因此必须将成功、信息和警告代码与错误代码一起映射。

  • ERROR_IO_PENDING-STATUS_PENDING是成功状态
  • ERROR_MORE_DATA-STATUS_BUFFER_OVERFLOW警告或STATUS_MORE_ENTRIES成功状态

您可以忽略 ReadFile 或 WriteFile 返回的任何非错误代码,并期待一个排队的完成项,但确定哪个是哪个可能有点痛苦。如果 Win32 错误代码组织得更好,那就太好了,但 Microsoft 确实提供了从NTSTATUSWin32 错误代码的映射:http: //support.microsoft.com/kb/113996。查看ntstatus.h平台 SDK 或您的 VS 安装以确定NTSTATUS代码的严重性。

当原始 API 调用返回时,可能会完成 IO 操作,例如刚刚从缓存中复制出来的读取请求(没有异步等待)。为了一致性起见,在这种情况下,完成消息仍将排队。

于 2011-03-31T13:28:29.107 回答
1
  • 是的,完全有ERROR_MORE_DATA可能出现在完成数据包中。您应该时刻准备好处理任何潜在的错误。在文档中GetQueuedCompletionStatus很清楚,当它返回时FALSE,您应该检查lpOverlapped参数是否为NULL. 如果不是NULL,则 I/O 完成数据包包含错误。

  • ReadFile默认行为是即使在或WriteFilereturn时,完成数据包也会排队到完成端口TRUE。从 Windows Vista 开始,可以更改此策略。请参阅 上的文档SetFileCompletionNotificationModes

于 2011-03-31T16:57:48.207 回答