boost::asio::bind_executor() 行为,是有意的吗?

boost::asio::bind_executor() behavior, is it intended?

本文关键字:bind asio executor boost 行为      更新时间:2023-10-16

我想在一个io_context中运行服务,并在另一个io_context中执行业务逻辑。但首先我想更多地了解重新调度行为,所以我写了一些实验性代码。这是我的第一个版本(不使用 boost::asio::bind_executor(((

boost::asio::io_context context1;
boost::asio::io_context context2;
// for simplicity I use post here, it will be socket operation in real code
boost::asio::post(context1, [&context2]()
{ boost::asio::post(context2, []() { printf("job finished"); }); });
// notice I didn't run context1 here
context2.run();

上下文1 未运行,在本例中,没有作业发布到上下文 2。所以 context2.run(( 立即返回。当然,屏幕上没有打印任何东西。

然后这是使用boost::asio::bind_executor((的第二个版本

boost::asio::io_context context1;
boost::asio::io_context context2;
boost::asio::post(context1, boost::asio::bind_executor(context2, []()
{ printf("job finished"); }));
// notice I didn't run context1 here
context2.run();

在这种情况下,进程永远卡在 context2.run(( 中,等待挂起的作业被交付。

所以手写的包装代码和 boost::asio::bind_executor(( 的行为不同。是错误还是故意的?哪一种是建议的方式?

提前致谢

在第二个示例中,您将要执行的函数发布到 context1(该函数未运行(,但将完成处理程序绑定到 conext2 的执行器。这意味着:

context1
  1. 异步操作处理器未执行该函数,因为 context1 未运行。
  2. context2 的异步事件解复用器等待事件在完成事件队列上发生,因此会阻止完成处理程序到 printf。这是因为它绑定到从队列中取消事件或结果的排队,并将其与完成处理程序相关联。

在第一个示例中,context2 的帖子位于 context1 的完成处理程序内,由于 context1 未运行,因此 context1 的异步操作处理器从未执行,因此,context1 的异步事件解复用器无需等待。尔格快速返回。

速推文档