我正在为基于IOCP的网络内容添加每次异步操作超时,这样我就可以在C++中拥有与JavaNIO.2类似的接口。我已经通过一个支持随机访问删除的优先级超时队列实现了这一点(这样,当一个操作成功完成时,我就可以删除它相关的超时)。
我的问题是如何处理超时的发生。现在,我使用与给定超时对应的重叠结构调用CancelIoEx。不过,我刚刚在MSDN上读到了这篇文章:
如果文件句柄与完成端口相关联,如果成功取消同步操作,则I/O完成包不会排队到端口。对于仍然挂起的异步操作,取消操作将为I/O完成包排队。
我使用使用完成处理程序扩展的重叠结构(每个操作用户提供了std::function,获取错误代码和编写/读取的字节),这些结构在完成包退出队列时执行(同样,类似于Java的NIO.2 API)。如果取消是异步发生的,则完成处理程序将像往常一样运行并得到ERROR_OPERATION_ABORTED。但是,如果CancelIoEx成功地立即取消了操作,该怎么办?听起来,根据上面的引号,我需要在这一点上执行处理程序,因为我以后不会得到一个完成包。但是,我如何知道是哪种情况,即是完成包排队,还是操作立即被取消?与其他异步操作不同,CancelIoEx不生成区分任务同步完成和异步完成的ERROR_IO_PENDING (在本例中为取消)。或者,我是不是读错了,任何重叠的操作都被认为是异步的(注意:我有而不是 set FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,但是这只适用于成功,而不是错误,并且我假设不会影响取消)?
发布于 2014-08-30 00:17:20
它不是在讨论CancelIoEx是同步还是异步,而是说I/O本身(例如ReadFile)是同步还是异步。它描述了同步和异步操作之间的行为差异。
如果文件句柄与完成端口相关联,如果成功取消同步操作,则I/O完成包不会排队到端口。对于仍然挂起的异步操作,取消操作将为I/O完成包排队。
同步操作--没有OVERLAPPED结构的操作,或者将立即完成的操作--将返回错误ERROR_OPERATION_ABORTED。
异步操作--具有不能立即完成的OVERLAPPED结构的操作--将有一个与ERROR_OPERATION_ABORTED一起排队的完成通知。
https://stackoverflow.com/questions/25577741
复制相似问题