用链/C ++ 20 Coroutine在Boost Asio中进行分解。适当的用法应该是什么样的?

问题描述 投票:0回答:1
asio::awaitable<void> progress(auto strand) { int i = 0; for (;;) { co_await dispatch(bind_executor(strand, asio::deferred)); ore::util::print("Strand Executor 1:", ++i); // ...Do something with a synchronous resource... co_await dispatch(asio::deferred); ore::util::print("Back on IO Context Executor"); // ...Code that doesn't depend on the synchronous resource... co_await dispatch(bind_executor(strand, asio::deferred)); ore::util::print("Strand Executor 2"); // ... Code that depends on the synchronous resource again... } } int main() { asio::io_context io; auto my_strand = make_strand(io); co_spawn(io, progress(my_strand), asio::detached); io.run(); }

这是(至少)一个问题,我对此感到好奇。因为我将链定义为:

auto my_strand = make_strand(io);

2.6k迭代左右后,最终将进行塞夫fault。

... T0 Strand Executor 1: 2657 T0 Back on IO Context Executor Segmentation fault (core dumped)

这似乎是ASIO内的堆栈大小爆炸,因为两个执行的链都来自同一执行人,但是我不清楚为什么会这样吗?

如果链来自不同的线程,则该作品的迭代正常运行:

    asio::thread_pool tp(1);
    auto my_strand = make_strand(tp);

...进行更多测试,我注意到它在更简单的测试中进行了测试:

asio::awaitable<void> progress() {
    for (;;) {
        co_await dispatch(asio::deferred);
    }
}

int main() {
    asio::io_context io;

    co_spawn(io, progress(), asio::detached);

    io.run();
}

也许Segfault与堆叠的Coroutine实现有关吗?我认为这应该是无堆的,但也许不是这样。

这三个问题:

为什么这是segfault?
为什么我在单独的executor上创建链,不是segfault

这是思考和创建链的正确方法?

注:由this Blog Post

修改的代码

  • 预知。是的。由于使用
  • dispatch
  • .
  • ,这种行为导致堆栈溢出
  • 如果您使用
post

没有这样的问题。使用dispatch允许ASIO在某些情况下“绕过”调度程序(其中至少是运行线程满足调度程序的需求,例如链接可用性),并直接在同一堆栈框架上调用处理程序。

e.g。
c++ c++20 boost-asio c++-coroutine
1个回答
0
投票

该函数用于要求链在其基础执行程序上执行给定功能对象。如果Strand并不忙,则该功能对象将在此函数内执行,并且如果基础执行程序的dispatch()函数也能够在返回之前执行该函数。

与the the the direct Docs的compare:

post

此功能提交一个使用对象的对象进行执行 关联的执行人。函数对象为执行,并且 在从当前线程返回之前,请勿从当前线程调用 post().

使用post()而不是延期,表示呼叫者的使用 偏爱函数对象被热切排队以执行。

这里的陷阱是,由于Coroutine模型,无限的环路可能会在这种方式中脱落。至少每次迭代一次打破直接调用链,您应该没事。 Caveat

,也要注意,将执行者切换到Coroutines中可能是反模式。我知道这是一个经常发生的问题,但我觉得这可能主要来自直接将基于相互排除到Asio Strand范式的老式并发的人。我想您会更快乐地拥抱信号(例如使用timers

,或者也许是类似的信号,例如
https://klemens.dev/sam/)或

Channels

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.