我正在尝试使用 Fiber 进行 boost asio 的试验,发现在使用 fiber示例中提供的轮询 asio 调度程序时,它的行为似乎有所boost::this_fiber::yield()
不同。boost::this_fiber::sleep_for(x)
设置是我们有一个线程创建两个无限循环的纤维:
- 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(); }
- 光纤 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 异步计时器的自包含示例,它表现出相同的行为。