2012-05-23 109 views
5

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

它一直工作得很好,直到我改变逻辑,使几个并发连接,并选择最快的一个。也就是说,当第一个async_read_some处理程序触发时,我取消其他套接字(关闭,关闭 - 所有内容),并继续使用当前的套接字。在95%的情况下,其他套接字的读处理程序会被调用operation_aborted错误。然而有时候,这些读处理程序被调用时没有错误,告诉我他们已经成功接收了N个字节。

但对于插座的文档::取消()states

此功能使所有未完成的异步连接,发送和接收 操作立即完成,并 业务取消的处理程序会通过boost::asio::error::operation_aborted错误。

所以,问题:我真的可以依靠生产代码中的operation_aborted错误吗?如果可以的话,这是Asio从boost 1.46.1中的一个错误吗?如果我不能,有没有关于这方面的官方文件?

+1

看起来你的情况是多个处理程序在调用cancel之前已经“成功”了。你可以依靠'operation_aborted'传递给尚未执行的任何处理程序(并且正在等待被调用)。 – Chad

回答

11

好了,答案:

  1. 不,我不能依靠只有operation_aborted错误。
  2. 当然,这不是阿西欧的缺陷,只是缺乏经验而已。
  3. 有一点官方documentation。这对定时器,没有插座,但同样的原则也适用:

如果计时器已过期取消时()被调用,那么处理程序异步等待操作将:

  • 已经被调用;或
  • 已经排队等候在不久的将来调用。

基本上,我是错误的假设,如果我使用一个线程io_service对象,那么每一个操作将被同时一些处理程序执行受阻。

我报道的行为实际上有很多意义,似乎每个使用Asio的人都知道这一点。我已经梳理了Asio的邮件列表,并发现了很多关于here,here,herehere这个主题的讨论。

例如,写入操作可能会成功完成,而 你是一个处理器中,但之前,你得四处打电话 插座取消,导致其完成处理程序被张贴到队列中。 据我所知,错误代码是由完成的 操作的状态决定的,而不是在 处理程序从队列中取出并执行时的套接字状态。

+1

+1为您自己的问题提供了简洁的答案 –

2

考虑同时建立两个连接。这两个处理程序都会触发,一个会先处理,另一个会在队列中(或在不同的线程中处理)。人们可以想到更多这样的例子。

所以为了实现您的需求,您需要更多的逻辑。

相关问题