我目前正在研究一种基于使用 IO 完成端口的命名管道的 IPC 机制。
不幸的是,我在使用 msdn 文档时遇到了一些问题,因为我不太清楚在哪些情况下调用 ReadFile/WriteFile 会导致完成数据包。
返回 FALSE 和 ERROR_IO_PENDING 的情况很清楚,但是当返回 ERROR_MORE_DATA 时,显然可能的情况又如何呢?这种情况下会有完成包吗?而且,如果返回其他错误怎么办? 在哪些情况下我必须直接处理结果和释放资源而不是在完成处理程序中?
另一种情况是 ReadFile/WriteFile 甚至成功,这显然也是可能的。 谢天谢地,MSDN 对此很清楚 here :
Further, the WriteFile function will sometimes return TRUE with a GetLastError value of ERROR_SUCCESS, even though it is using an asynchronous handle (which can also return FALSE with ERROR_IO_PENDING). ... In this example, the recommendation would be to allow the completion port routine to be solely responsible for all freeing operations for such resources.
这个建议是否在所有情况下都是正确的,并且实际上可以(并且应该)完全忽略分配给完成端口的句柄的 ReadFile/WriteFile 操作的结果,因为无论如何都会将数据包发送到端口?
最佳答案
只要 IO 操作能够启动,就会有一个 IO 完成项排队等候 IO 操作。无论IO操作开始后是否遇到错误,都会有一个完成项排队到完成端口。
IO 系统返回的 NTSTATUS
代码与 Win32 错误代码之间存在映射问题,这使得很难区分哪些状态是错误,哪些只是信息性的。 NTSTATUS
,被内核和原生API使用,有四个严重级别:success、information、warning和error。除了错误代码之外的任何内容都表明 IO 操作能够启动。 Win32 只有一种严重性 (ERROR_*
),因此成功、信息和警告代码必须与错误代码一起映射。
ERROR_IO_PENDING
-STATUS_PENDING
是成功状态ERROR_MORE_DATA
-STATUS_BUFFER_OVERFLOW
警告或STATUS_MORE_ENTRIES
成功状态
您可以忽略 ReadFile 或 WriteFile 返回的任何非错误代码并期待一个排队的完成项目,但确定哪个是哪个可能有点痛苦。如果能更好地组织 Win32 错误代码就好了,但 Microsoft 确实提供了从 NTSTATUS
到 Win32 错误代码的映射:http://support.microsoft.com/kb/113996 .请参阅平台 SDK 或您的 VS 安装中的 ntstatus.h
以确定 NTSTATUS
代码的严重性。
IO 操作有可能在原始 API 调用返回时完成,例如刚刚从缓存中复制出来的读取请求(无需异步等待)。在这种情况下,为了保持一致性,完成消息仍将排队。
关于windows - 什么时候发送IO完成端口包,什么时候不发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3130785/