c++ 使用boostasio链作为“互斥体”在协程中不起作用

uwopmtnx  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(155)

我正在做一个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_threadAssert失败!
我在Linux上使用Boost v1.81.0。

kg7wmglp

kg7wmglp1#

post中指定的执行器只是一个后备。令牌/处理程序的关联执行器优先。在您的例子中,相关的执行器是协程的链。您切换执行器的尝试没有任何作用。要强制选择executor,您可以确保它与token * 关联 *:

post(bind_executor(my_strand, yield));

字符串
和/或

post(bind_executor(ioctx, yield));

相关问题