c++ - async_connect() 超时,多个线程执行 io_service.run()

标签 c++ boost boost-asio

我正在尝试实现带有超时的 async_connect()。

    async_connect_with_timeout(socket_type & s,
        std::function<void(BoostAndCustomError const & error)> const & connect_handler,
        time_type timeout);

当操作完成时,connect_handler(error) 被调用,error 指示操作结果(包括超时)。

我希望使用 timeouts example 1.51 中的代码.最大的区别是我使用多个工作线程执行 io_service.run()。

要使示例代码正常运行需要进行哪些更改?

我的问题是:

  1. 调用时:

    Start() {
        socket_.async_connect(Handleconnect);
        dealine_.async_wait(HandleTimeout);
    }
    

    HandleConnect() 甚至可以在 async_wait() 之前在另一个线程中完成(不太可能但可能)。我是否必须 strand 包装 Start()HandleConnect()HandleTimeout()

  2. 如果首先调用 HandleConnect() 没有错误,但是 deadline_timer.cancel()deadline_timer.expires_from_now() 会怎样失败是因为 HandleTimeout()“已排队等候在不久的将来调用”?看起来示例代码让 HandleTimeout() 关闭套接字。这种行为(连接后我们愉快地开始一些操作后定时器关闭连接)很容易导致严重的头痛。

  3. 如果先调用 HandleTimeout()socket.close() 会怎样?是否有可能 HandlerConnect() 已经“排队”而没有错误?文档说:“任何异步发送、接收或连接操作都将立即取消,并以 boost::asio::error::operation_aborted 错误完成”。多线程环境下的“立即”是什么意思?

最佳答案

  1. 如果你想防止它们在不同线程中并行执行,你应该用 strand 包裹每个处理程序。我猜某些完成处理程序会访问 socket_ 或计时器,因此您肯定还必须用 strand 包裹 Start()。但是使用 io_service-per-CPU 模型不是更简单吗,即将您的应用程序基于 io_service 池?恕我直言,你会少很多头痛。

  2. 是的,这是可能的。为什么会头疼?套接字因“假超时”而关闭,您开始重新连接(或其他)过程,就像它因网络故障而关闭一样。

  3. 是的,这也是可能的,但同样,它不应该对正确设计的程序造成任何问题:如果在 HandleConnect 中您尝试在关闭的套接字上发出一些操作,您会得到适当的错误。无论如何,当您尝试发送/接收数据时,您并不知道当前的套接字/网络状态。

关于c++ - async_connect() 超时,多个线程执行 io_service.run(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13496523/

相关文章:

c++ - 从 Python 调用 IB API

c++ - Boost-Asio:如何处理来自控制台和网络的流数据?

c++ - 打印奇数

c++ - Sprite 和子弹不移动 C++

C++ OpenGL 游戏计时器

c++ - 如何使用 boost split 拆分字符串并忽略空值?

c++ - 范围限制资源管理 (SBRM) 是什么意思?

c++ - boost::asio 如何以正确的方式读取完整缓冲区?

c++ - Boost ASIO 中的资源暂时不可用

c++ - 如何在 Windows 中使用 boost asio 从命令行异步读取输入?