我正在为我的基于 IOCP 的网络添加每异步操作超时,因此我可以在 C++ 中拥有与 Java 的 NIO.2 使用类似的接口(interface)。我已经使用支持随机访问删除的超时优先级队列实现了这一点(这样当操作成功完成时,我可以删除其关联的超时)。
我的问题是如何处理超时的发生。现在,我使用与给定超时对应的重叠结构调用 CancelIoEx。但是,我刚刚在 MSDN 上阅读了这个:
If the file handle is associated with a completion port, an I/O completion packet is not queued to the port if a synchronous operation is successfully canceled. For asynchronous operations still pending, the cancel operation will queue an I/O completion packet.
我使用扩展完成处理程序的重叠结构(每个操作用户提供 std::function 获取错误代码和写入/读取的字节),只要完成数据包出队(同样,非常像 Java 的 NIO.2 API)就会执行。如果取消是异步发生的,那么完成处理程序将照常运行并获得 ERROR_OPERATION_ABORTED。但是如果 CancelIoEx 成功立即取消操作呢?听起来,根据上面的引述,我需要在那个时候执行处理程序,因为我以后不会得到完成数据包。但是我怎么知道是哪种情况,即完成数据包是排队还是立即取消了操作???与其他异步操作不同,CancelIoEx 不会产生用于区分同步和异步完成任务(在本例中为取消)的 ERROR_IO_PENDING。或者,我读错了吗,任何重叠的操作都被认为是异步的(注意:我没有设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,但话又说回来,这只适用于成功,而不适用于错误,我认为不会影响取消)?
最佳答案
这不是在谈论 CancelIoEx
是同步还是异步,而是在说 I/O 本身(例如 ReadFile
)是同步还是异步。它描述了同步和异步操作之间的行为差异。
If the file handle is associated with a completion port, an I/O completion packet is not queued to the port if a synchronous operation is successfully canceled. For asynchronous operations still pending, the cancel operation will queue an I/O completion packet.
同步操作——没有OVERLAPPED
结构的操作,或者会立即完成的操作——将返回错误ERROR_OPERATION_ABORTED
。
异步操作 - 具有无法立即完成的 OVERLAPPED
结构的操作 - 将有一个带有 ERROR_OPERATION_ABORTED
的完成通知排队。
关于c++ - 检测 CancelIoEx 是否同步取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25577741/