boost :: asio async处理程序在取消后调用没有错误 [英] boost::asio async handlers invoked without error after cancellation

查看:386
本文介绍了boost :: asio async处理程序在取消后调用没有错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码在单个线程中使用boost :: asio和io_service来执行各种套接字操作。所有操作都是异步的,每个处理程序依赖于 boost :: system :: error_code (特别是 boost :: asio :: error :: operation_aborted )来确定操作的结果。

My code uses boost::asio and io_service in a single thread to perform various socket operations. All operations are asynchronous and every handler depends on the boost::system::error_code (particularly boost::asio::error::operation_aborted) to determine the result of the operation.

它一直工作得很好,直到我改变逻辑,使几个并发连接和选择最快的一个。也就是说,当第一个 async_read_some 处理程序触发时,我取消其他套接字(关闭,关闭 - 一切),继续当前的。在95%的情况下,使用operation_aborted错误调用其他套接字的读取处理程序。

It's been working perfectly well until I changed the logic to make several concurrent connections and pick the fastest one. That is, when the first async_read_some handler fires, I cancel other sockets (shutdown, close - everything) and proceed with the current one. In 95% of cases other sockets' read handlers are invoked with the operation_aborted error. However sometimes, these read handlers are invoked without errors, telling me that they have successfully received N bytes.

但是有关socket :: cancel()的文档

But the documentation for socket::cancel() states:


此函数使所有未完成的异步连接,发送和
接收操作立即完成,并且
取消操作的处理程序将被传递 boost :: asio :: error :: operation_aborted 错误。

,问题:我真的可以依赖生产代码中的 operation_aborted 错误吗?如果可以的话,这是一个在Asio从boost 1.46.1的错误?

So, the questions: Can I really rely on the operation_aborted error in production code? If I can, is it a bug in Asio from boost 1.46.1? If I can't, is there any official documentation regarding this?

推荐答案

好的,答案:


  1. 不,我不能依赖 operation_aborted 错误。

  2. 当然,这不是Asio的错误,只是在我身边缺乏经验。

  3. 有一点官方文档。这是为计时器而不是套接字,但同样的原则适用:

  1. No, I cannot rely on the operation_aborted error only.
  2. Of course, it's not a bug in Asio, just a lack of experience on my side.
  3. There is a little bit of official documentation. It's for timers, not sockets, however the same principles apply:






在调用cancel()时已经过期,那么用于异步等待操作的处理程序将:


If the timer has already expired when cancel() is called, then the handlers for asynchronous wait operations will:


  • 已经被调用;或

  • 已排队等待调用。

基本上,我错误的假设,如果我使用一个单一的线程io_service,那么每一个操作将被阻塞,而一些处理程序执行。

Basically, I was wrong in assumption that if I use a single thread for io_service, then every operation will be blocked while some handler executes.

我报告的行为实际上是很有道理的,看起来每个使用Asio的人都知道。我梳理了Asio的邮件列表,并发现了很多关于此主题的讨论这里此处此处此处

The behavior I'm reporting actually makes a lot of sense and it seems that everyone who uses Asio knows that. I've combed through Asio's mailing lists and have found a lot of discussion on the subject here, here, here and here.


例如,一个写操作可能成功完成,而
你在一个处理程序中,但在你走到调用
套接字取消之前,导致它的完成处理程序发布到队列。
根据我的理解,错误代码由完成的
操作的状态决定,而不是在
处理程序从队列中取出并执行时套接字的状态。

For instance, a write operation may complete successfully while you are inside a handler but before you have got around to calling socket cancel, causing its completion handler to be posted to the queue. As I understand it, the error code is determined by the status of the operation that completed, not the state of the socket at the time the handler is picked off the queue and executed.

这篇关于boost :: asio async处理程序在取消后调用没有错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆