手动驱动非阻塞原生句柄的最基本的 Asio 执行上下文是什么?

What is the most basic Asio execution context for manually driving non-blocking native handles?

假设我有一个现有程序,现有主循环已完成 "the traditional way",我可以注册以在文件描述符可读时收到通知,等等。为了这个问题的目的,我们假设我们不想修改此循环以使用 Asio。

看来我可以采用,例如,Asio 数据报套接字,将其设置为 native_non_blocking(),监视其 fd 以获取读取事件,然后通过执行 "blocking" 对此类事件做出反应receive_from() 调用并期望它们通过 error_code return 相当于 EAGAINEWOULDBLOCK。同样写。

(暂且不管这是否是Asio的"in the spirit",这不是问题的真正目的。)

那么我的问题是,要执行此操作我需要提供的最低执行上下文是什么?似乎我真的不需要 io_context(例如,在 Linux 上,它会为 epoll、signalfd 和 timerfd 打开一些额外的 fds)因为我实际上永远不应该 使用它。似乎我真的不想 system_contextthread_pool 因为我真的不想在其他一些线程上 运行 任何东西。

是否有一些适合此处的预定义 "same thread" 上下文?如果现在,人们将如何构建这样的东西?或者,即使在制作 "blocking" receive_from()send_to() 在一些隐藏的微事件循环中调用非阻塞套接字(如果是,为什么)?

Is there some pre-defined "same thread" context that would be appropriate here?

io_context 只提供上下文,不包含任何关于线程使用它的信息。因此

boost::asio::io_context io;
io.run();

已经是你的最小上下文了。

你的困惑似乎来自于 run() 打算提供事件循环,这似乎是阻塞行为。有两种方法:

  • 不要在任何地方调用 run()(这会限制你的选择,但如果你真的只是发誓要使用本机后门(native_handle() 和朋友)你不应该在意.

  • run_one()poll_one() 集成到您的事件循环中并快乐起来。这允许您使用构建在 io_context 抽象及其执行程序上的全部 Asio 服务,同时您显然也可以使用后门程序¹。

旁注:不要忘记正确处理来自 {run,poll}[_one]()

的异常

¹ 风险由您自行承担,因为结合使用它们意味着您了解对您要支持的所有平台的影响