我的代码在单个线程中使用boost :: asio和io_service来执行各种套接字操作。所有操作都是异步的,每个处理程序都依赖于boost::system::error_code
(特别是boost::asio::error::operation_aborted
)来确定操作的结果。
在我改变逻辑以创建几个并发连接并选择最快的连接之前,它一直运行良好。也就是说,当第一个async_read_some
处理程序触发时,我取消其他套接字(关闭,关闭 - 所有内容)并继续当前的套接字。在95%的情况下,使用operation_aborted错误调用其他套接字的读取处理程序。但有时,这些读取处理程序被调用而没有错误,告诉我它们已经成功接收了N个字节。
但是socket :: cancel()states的文档:
此函数会导致所有未完成的异步连接,发送和 接收立即完成的操作,以及处理程序 取消的操作将传递
boost::asio::error::operation_aborted
错误。
所以,问题:我真的可以依赖生产代码中的operation_aborted
错误吗?如果可以的话,它是来自增强1.46.1的Asio中的一个错误吗?如果我不能,是否有关于此的官方文件?
答案 0 :(得分:12)
好的,答案是:
operation_aborted
错误。如果在调用cancel()时定时器已经过期,那么异步等待操作的处理程序将:
基本上,我假设如果我为io_service使用单个线程,那么在执行某些处理程序时将阻止每个操作。
我报告的行为实际上很有意义,似乎每个使用Asio的人都知道这一点。我已经梳理了Asio的邮件列表,并就主题here,here,here和here进行了大量讨论。
例如,写操作可能会成功完成 你是在处理程序内,但在你开始打电话之前 套接字取消,导致其完成处理程序被发布到队列中。 据我了解,错误代码由状态决定 完成的操作,而不是当时套接字的状态 处理程序从队列中删除并执行。
答案 1 :(得分:2)
考虑同时建立两个连接。两个处理程序都将触发,一个将首先处理,第二个处于队列中(或在另一个线程上处理)。人们可以想到更多这样的例子。
因此,为了实现您的要求,您需要更多的逻辑。