IO完成端口数据包何时发送、何时不发送?

mfy*_*fya 5 windows winapi named-pipes overlapped-io io-completion-ports

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

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

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

另一种情况是 ReadFile/WriteFile 甚至成功,这显然也是可能的。值得庆幸的是,MSDN对此非常清楚:

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

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

Chr*_*ith 4

只要 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 返回的任何非错误代码并期望排队的完成项,但确定哪个是哪个可能有点痛苦。NTSTATUS如果 Win32 错误代码能够更好地组织起来就好了,但是 Microsoft 确实提供了到 Win32 错误代码的映射: http://support.microsoft.com/kb/113996。请参阅ntstatus.h平台 SDK 或 VS 安装以确定代码的严重性NTSTATUS

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