1

我正在尝试使用 Fiber 进行 boost asio 的试验,发现在使用 fiber示例中提供的轮询 asio 调度程序时,它的行为似乎有所boost::this_fiber::yield()不同。boost::this_fiber::sleep_for(x)

设置是我们有一个线程创建两个无限循环的纤维:

  1. Fiber 1 使用带有野兽 websocket 的异步读取。
     while (true) {
       beast::flat_buffer buffer;
       boost::system::error_code ec;
       ws.async_read(buffer, boost::fibers::asio::yield[ec]);
       LOG(INFO) << beast::make_printable(buffer.data());
       boost::this_fiber::yield();
     }
    
  1. 光纤 2 只是循环和输出。
     while (true) {
       boost::this_fiber::yield();
     }
    

使用此设置,实际上不会发生任何 websocket 读取,因为我们永远不会在async_read. 但是,如果我们将光纤 2 切换为

    while (true) {
      boost::this_fiber::sleep_for(std::chrono::milliseconds(10));
    }

我们现在可以打印出 websocket 读取。奇怪的是,如果我们将 sleep_for 时间减少到一个较低的数字,例如std::chrono::nanoseconds(1),则不再发生读取。

为什么会出现这种行为?这是轮询 asio 调度程序的一个微妙之处吗?我的假设是,Fiber 2boost::this_fiber::yield()会以某种方式阻止 io_context 运行任何完成处理程序,但我很不确定。

谢谢!

编辑:

可以在此处找到一个带有 asio 异步计时器的自包含示例,它表现出相同的行为。

4

0 回答 0