从链执行器上运行的 spawn 方法生成时的任务优先级

Task prioritization when yielding from spawn method running on strand executor

提问人:Zohar81 提问时间:9/13/2023 最后编辑:Zohar81 更新时间:9/14/2023 访问量:39

问:

我想分析使用 strin 的 boost.asio 调用的顺序。

请考虑以下情况。首先,使用链的协程由(任务 1)调用,它以独占方式运行,因为我使用链,直到当指令指针到达 *** 时它协同挂起,并且在线程上运行的调度程序执行下一个处理程序(任务 2)。boost::asio::spawn

任务 2 使用相同的链,但它由 调用。此调用保证此任务在完成之前具有独占性(无收益)。boost::asio::post

因此,我预计在这种情况下,至少在任务 2 完成之前不会执行任务 1 的其余部分。我的假设正确吗?

此外,如果在执行任务 2 时,在同一条链上调用了更多任务,任务 1 在任务 2 终止时是否获得优先级,或者无法保证哪个任务将接管该链(任务 2 刚刚从 yield 返回或调用的新任务)

//task1
boost::asio::spawn(strand_, [=](const auto& yield) {
  ...
  ..
  .
  auto response = sendRequest(request, yield);   //(***)
  ...
  ..
  .
}

//task 2 
boost::asio::post(strand_, [&]() {
  ... 
  ..
  .
}

//task 3
boost::asio::post(strand_, [&]() {
  ... 
  ..
  .
}

C++ 提升 同步 ASIO

评论

0赞 sehe 9/14/2023
措辞比以前好多了。不过,精确一点会有所帮助。例如,“我使用链,直到达到需要线程执行下一个任务(任务 2)的产量”——没有这样的事情发生。你不会“达到收益”。暂停协程。没有什么“走线”。相反,在线程上运行的调度程序将执行下一个处理程序(在上下文中应为任务 2)
1赞 Zohar81 9/14/2023
感谢您的评论(一如既往),修改了措辞。如果您仍然认为它不够清晰,请随意编辑。

答:

1赞 sehe 9/14/2023 #1

因此,我预计在这种情况下,至少在任务 2 完成之前不会执行任务 1 的其余部分。我的假设正确吗?

是的

此外,如果在执行任务 2 时,在同一条链上调用了更多任务,任务 1 在任务 2 终止时是否获得优先级,或者无法保证哪个任务将接管该链(任务 2 刚刚从 yield 返回或调用的新任务)

如果“调用任务”是指“发布处理程序”(或等效地:“启动异步操作”),是的。链上的所有任务都按过帐顺序执行。

这记录在这里:处理程序调用的顺序

处理程序调用的顺序

给定:一个 strand 对象s

  • 满足完成处理程序要求的对象a
  • 一个对象,它是实现的任意副本a1a
  • 满足完成处理程序要求的对象b
  • 一个对象,它是实现的任意副本b1b

如果满足以下任一条件:

  • s.post(a)发生之前s.post(b)
  • s.post(a)happens-before ,其中后者在链外执行s.dispatch(b)
  • s.dispatch(a)happens-before ,其中前者在链外执行s.post(b)
  • s.dispatch(a)happens-before ,其中两者都在链外执行s.dispatch(b)

然后发生-之前.asio_handler_invoke(a1, &a1)asio_handler_invoke(b1, &b1)

在您的例子中,happens-before 是存在的(因为您知道 task1 的延续必须在输入 task2 之前发布)。