首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确定何时完成CancelIo()?

如何确定何时完成CancelIo()?
EN

Stack Overflow用户
提问于 2010-10-13 05:51:21
回答 3查看 4.6K关注 0票数 2

CancelIo()应该取消与调用线程关联的所有挂起的 I/O操作。根据我的经验,CancelIo()有时也会取消未来的 I/O操作。给予:

代码语言:javascript
复制
ReadFile(port, buffer, length, &bytesTransferred, overlapped);
  1. 如果我在读取之前立即调用CancelIo(port)GetQueuedCompletionStatus()将永远阻塞,永远不会接收读取操作。
  2. 如果在读取后立即调用CancelIo(port)GetQueuedCompletionStatus()将返回带GetLastError()==ERROR_OPERATION_ABORTED的0
  3. 如果我调用CancelIo(port),并且没有挂起或后续的读取,GetQueuedCompletionStatus()将永远阻塞。

这里的关键点是,无法检测CancelIo()何时已完成执行。如何确保CancelIo()已完成执行,并且发出进一步的读取请求是安全的?

PS:从http://osdir.com/ml/lib.boost.asio.user/2008-02/msg00074.htmlasio/using.html的角度看,CancelIo()听起来不太实用。客户必须需要Windows支持。我有什么选择?

注意::我是从串行端口读取的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-16 21:30:31

CancelIo()工作得很好。我误解了我的代码。

经过进一步研究,发现代码调用的是CancelIo(),后面是带有超时INFINITEReadFile()。完成端口从未收到读取的通知,因为远程端从未发送任何内容。换句话说,CancelIo()没有取消后续的操作。

我发现了一些令人眼花缭乱的文档这里

在为异步I/O编写代码时要小心,因为如果需要,系统保留使操作同步的权利。因此,最好是编写程序以正确处理可以同步或异步完成的I/O操作。示例代码演示了这一点。

结果表明,如果正在读取的数据已经被设备驱动程序缓存,设备驱动程序可以选择以同步方式处理异步操作。经过进一步研究,我发现当CancelIo()ReadFile()之前被调用时,有时会导致后者同步返回。我不知道为什么完成端口在ReadFile()之后从未收到有关CancelIo()的通知,但是我不能再重现这个问题。

无论ReadFile()是同步的还是异步的,完成端口都会被发出信号。

票数 4
EN

Stack Overflow用户

发布于 2010-10-13 06:13:03

等待(可能是零超时) overlapped.Handle。将设置操作是否完成或取消。

票数 3
EN

Stack Overflow用户

发布于 2010-10-13 17:58:46

如果您已经在使用重叠操作,那么为什么要取消I/O呢?“取消”飞行中I/O操作的整个概念实际上是很容易发生竞争的,并且完全受制于您试图写入的底层设备堆栈;您唯一想要这样做的时候就是打开另一个等待完成该I/O的线程。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3921111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档