我想使用strand分析boost.asio调用的顺序。
考虑以下场景。首先,使用链的协程由
boost::asio::spawn
(任务 1)调用,自从我使用链以来,它一直在专门运行,直到达到让线程执行下一个任务(任务 2)的收益。
任务 2 使用相同的链,但由
boost::asio::post
调用。此调用保证此任务在完成之前获得排他性(无收益)。
所以我预计在这种情况下,任务 1 的剩余部分至少要等到任务 2 完成后才会执行。我的假设正确吗?
此外,如果在执行任务 2 时,同一链上调用了更多任务,当任务 2 终止时任务 1 是否获得优先级,或者无法保证哪个任务将占用该链(任务 2 刚刚从产生或调用的更新任务)
//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_, [&]() {
...
..
.
}
所以我预计在这种情况下,任务 1 的剩余部分至少要等到任务 2 完成后才会执行。我的假设正确吗?
是的
此外,如果在执行任务 2 时,同一链上调用了更多任务,当任务 2 终止时任务 1 是否获得优先级,或者无法保证哪个任务将占用该链(任务 2 刚刚从产生或调用的更新任务)
如果“调用任务”的意思是“发布处理程序”(或等效:“启动异步操作”),是的。链上的所有任务都按照发布的顺序执行。
这记录在此处:
处理程序按照发布的顺序执行,文档:处理程序调用顺序:
处理程序调用顺序
给出:一个strand对象
s
- 一个对象
满足完成处理程序要求a
- 一个对象
,它是由实现制作的a1
的任意副本a
- 一个对象
满足完成处理程序要求b
- 一个对象
,它是由实现制作的b1
的任意副本b
如果满足以下任一条件:
- 之前
发生在s.post(a)
s.post(b)
发生在s.post(a)
之前,后者在链外执行s.dispatch(b)
发生在s.dispatch(a)
之前,前者在链外执行s.post(b)
发生在s.dispatch(a)
之前,两者都在链之外执行s.dispatch(b)
然后
发生在asio_handler_invoke(a1, &a1)
之前。asio_handler_invoke(b1, &b1)
在您的情况下,发生之前存在(因为您知道任务 1 的延续必须在输入任务 2 之前发布)。