执行io_service.run()的多个线程的async_connect()超时

时间:2012-11-21 15:29:41

标签: 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()之前在另一个线程中完成(不太可能但可能)。我是否必须strandStart()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 个答案:

答案 0 :(得分:1)

  1. 如果你想阻止它们在不同的线程中并行执行,你应该使用strand包装每个处理程序。我猜一些完成处理程序会访问socket_或计时器,所以你肯定必须用{@ 1}}来包裹Start()。但是,使用io_service-per-CPU模型,即将应用程序基于io_service池,是不是更简单?恕我直言,你会轻而易举地

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

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