我正在做一个boost asio项目,其中我有一堆堆栈式协同程序(https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/overview/composition/spawn.html),执行异步操作,我使用一个strand来同步对关键部分的访问,如下所示:
io_context ioctx;
io_context::strand my_strand{ioctx};
void my_coroutine(yield_context yield) {
while (true) {
post(my_strand, yield);
// Critical section, where one coroutine is supposed to have access
post(ioctx, yield);
}
}
字符串
然而,我开始怀疑互斥并没有发生,并写了一个小测试来测试我的假设:
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
using namespace boost::asio;
io_context ioctx;
io_context::strand my_strand{ioctx};
std::atomic_int cnt{0};
void my_coroutine(yield_context yield) {
while (true) {
post(my_strand, yield);
cnt++;
assert(cnt == 1);
assert(my_strand.running_in_this_thread());
cnt--;
post(ioctx, yield);
}
}
int main() {
spawn(ioctx, [&](yield_context yield) { my_coroutine(yield); });
spawn(ioctx, [&](yield_context yield) { my_coroutine(yield); });
for (int i = 0; i < 5; ++i) {
std::thread([] { ioctx.run(); }).detach();
}
getchar();
}
型
正如我所怀疑的,当程序运行时,两个Assert都失败了。我不知道问题在哪里。最令人惊讶的是,注解掉其中一个spawn调用仍然会导致running_in_this_thread
Assert失败!
我在Linux上使用Boost v1.81.0。
1条答案
按热度按时间kg7wmglp1#
post
中指定的执行器只是一个后备。令牌/处理程序的关联执行器优先。在您的例子中,相关的执行器是协程的链。您切换执行器的尝试没有任何作用。要强制选择executor,您可以确保它与token * 关联 *:字符串
和/或
型