asio::io_context::run_one() 和 while()

Posted

技术标签:

【中文标题】asio::io_context::run_one() 和 while()【英文标题】:asio::io_context::run_one() with while() 【发布时间】:2019-02-01 16:47:17 【问题描述】:

在下面的代码中使用asio::io_context::run_one() 时,为什么我们需要while 循环?如果我们不使用while 循环会怎样,如下所示?

size_t numberOfHandler = sock.io_service().run_one();

void set_result(optional<error_code>* a, error_code b)
  
    a->reset(b);
  

template <typename MutableBufferSequence>
  void read_with_timeout(tcp::socket& sock,
      const MutableBufferSequence& buffers)
  
    optional<error_code> timer_result;
    deadline_timer timer(sock.io_service());
    timer.expires_from_now(seconds(1));
    timer.async_wait(boost::bind(set_result, &timer_result, _1));
    optional<error_code> read_result;
    async_read(sock, buffers,
        boost::bind(set_result, &read_result, _1));

    sock.io_service().reset();
    while (sock.io_service().run_one())
    
      if (read_result)
        timer.cancel();
      else if (timer_result)
        sock.cancel();
    
    if (*read_result)
      throw system_error(*read_result);
  

【问题讨论】:

【参考方案1】:

您需要使用 while 循环来处理所有处理程序以在超时已过且无法在此超时内读取数据时抛出异常。

async_wait的handler在async_read的handler之前执行的情况意味着socket无法在1秒内读取数据。

1. run_one is called
2. handler passed into async_wait is called
3. timer_result is set
4. else if (timer_result) is processed
5. sock.cancel() is called [ cancel() queues handler with error code !! 
       which indicates that read operation was aborted]
6. handler passed into async_read is queued

传入async_read 的处理程序已排队,但何时调用?只能由run_one 调用。如果未调用此处理程序,则无法设置 read_result。那么,您想如何指示在某些超时内无法读取数据的情况呢? read_result 只能通过调用run_one 中的处理程序来设置。这就是为什么您需要在循环内处理 run_one 以调用处理程序,该处理程序将 read_result 设置为可选,错误代码指示已中止读取操作。

【讨论】:

以上是关于asio::io_context::run_one() 和 while()的主要内容,如果未能解决你的问题,请参考以下文章