IOCP:如果操作立即返回错误,我还能收到完成通知吗?

Posted

技术标签:

【中文标题】IOCP:如果操作立即返回错误,我还能收到完成通知吗?【英文标题】:IOCP: If operation returns immediately with error, can I still receive completion notification? 【发布时间】:2014-08-15 22:08:15 【问题描述】:

如果 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 启用,那么即使操作立即成功完成,我仍然会在完成端口上收到完成通知。我想知道如果它立即完成并出现错误是否是这种情况。

我使用在扩展的 OVERLAPPED 结构中存储为 std::function 的处理程序处理完成,并由在完成端口上循环的线程池执行。禁用 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 意味着我不必担心处理程序会形成递归链,最坏的情况是,如果操作经常立即完成,则会耗尽堆栈空间。启用跳过后,如果操作立即返回,则必须立即调用新操作的处理程序。

问题是处理程序应该在成功和错误时都执行。但是,我不知道是否重叠的 Read/Write/WSARecv/WSASend 立即返回并出现错误仍会将完成数据包排队,以便我可以允许线程池在处理程序中对其进行处理,如成功案例。这是可行的吗?它是否只适用于某些类型的错误而不适用于其他类型的错误?解决方法?

【问题讨论】:

如果你得到一个错误并且它不是 ERROR_IO_PENDING 那么,不,操作从未开始所以无法完成。 我不确定,但我认为汉斯是对的。 (我希望如此;否则,由于某些故障模式会阻止对完成数据包进行排队,因此您永远不会知道自己是否会得到一个。)但是,如果出现这种情况,您始终可以通过自己发布一个完成数据包来处理这种情况是合适的。 【参考方案1】:

This knowledge base article 表示 SUCCESS 和 ERROR_IO_PENDING 会导致生成完成数据包,而其他结果则不会。

见技巧 4

【讨论】:

【参考方案2】:

基于this blog from Raymond Chen,即使操作同步完成(成功或有错误条件),所有完成都将排队到完成端口。

【讨论】:

Raymond 正在讨论 I/O 成功的情况,我不相信您可以得出结论,当 I/O 失败时也是如此。并且显然存在排除通知的故障模式,例如,如果句柄无效。

以上是关于IOCP:如果操作立即返回错误,我还能收到完成通知吗?的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以使用 IOCP 来通知套接字何时可读/可写?

IOCP 线程 - 澄清?

Windows完成端口 IOCP模型

IOCP模型EPOLL模型的比较以及游戏服务器端的一些建议

技术派-epoll和IOCP之比较

WinSock IOCP 模型总结(附一个带缓存池的IOCP类)