asio :: io_context :: run_one () с помощью while () - PullRequest
0 голосов
/ 01 февраля 2019

Зачем нам нужен цикл while при использовании asio::io_context::run_one() в следующем коде?Что если мы не используем цикл 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 Ответ

0 голосов
/ 02 февраля 2019

Вам необходимо использовать цикл while для обработки всех обработчиков, которые выдают исключение, когда истек тайм-аут и данные не могут быть прочитаны в течение этого тайм-аута.

Ситуация, когда обработчик async_wait выполняется до async_readОбработчик означает, что сокет не может прочитать данные за 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 с кодом ошибки, который указывает на прерванную операцию чтения.

...