gpt4 book ai didi

c++ - 如何等待所有 boost 完成 :asio's stackful coroutines?

转载 作者:可可西里 更新时间:2023-11-01 18:39:04 25 4
gpt4 key购买 nike

我正在用 asio::spawn 启动一些协程,我想等到所有协程都完成后再做一些其他工作。如何实现?

控制流程如下:

asio::spawn (io, [] (asio::yield_context yield) {
...
// starting few coroutines
asio::spawn (yield, [] (asio::yield_context yield2) { ... });
asio::spawn (yield, [] (asio::yield_context yield2) { ... });
asio::spawn (yield, [] (asio::yield_context yield2) { ... });
asio::spawn (yield, [] (asio::yield_context yield2) { ... });

// now I want to wait for all of them to finish before I do
// some other work?
...
});

io.run ();

更新

下面是示例代码

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
#include <chrono>

#include <iostream>
using namespace std;

int main ()
{
using namespace boost::asio;

io_service io;

spawn (io, [&] (yield_context yield) {
cout << "main coro starts\n";

auto lambda = [&] (yield_context yield)
{
cout << "in lambda inside subcoroutine - starts\n";
steady_timer t (io, std::chrono::seconds (1));
t.async_wait (yield);
cout << "in lambda inside subcoroutine - finishes\n";
};

// starting few coroutines
spawn (yield, lambda);
spawn (yield, lambda);

// now I want to wait for all of them to finish before I do
// some other work?
// ???

cout << "main coro finishes\n";
});

io.run ();
}

输出是:

// main coro starts
// in lambda inside subcoroutine - starts
// in lambda inside subcoroutine - starts
// main coro finishes <----
// in lambda inside subcoroutine - finishes
// in lambda inside subcoroutine - finishes

在我期待的时候:

// main coro starts
// in lambda inside subcoroutine - starts
// in lambda inside subcoroutine - starts
// in lambda inside subcoroutine - finishes
// in lambda inside subcoroutine - finishes
// main coro finishes

(参见“main coro finishes”行的位置)

最佳答案

我找到了一种……某种解决方法。

我可以使用无限持续时间的计时器,并从最后一个子协程中取消它。这将唤醒主协程。

Coliru Example

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>

#include <iostream>
using namespace std;

int main ()
{
using namespace boost::asio;

io_service io;

spawn (io, [&] (yield_context yield) {
cout << "main coro starts\n";


steady_timer rendez_vous (io, steady_timer::clock_type::duration::max ());
/* volatile */ int counter = 2;


auto lambda = [&] (yield_context yield)
{
cout << "in lambda inside subcoroutine - starts\n";
steady_timer t (io, boost::chrono::seconds (1));
t.async_wait (yield);
cout << "in lambda inside subcoroutine - finishes\n";

if (--counter == 0)
rendez_vous.cancel ();
};

// starting few coroutines
spawn (yield, lambda);
spawn (yield, lambda);

// now I want to wait for all of them to finish before I do
// some other work?
// ???
boost::system::error_code ignored_ec;
rendez_vous.async_wait (yield [ignored_ec]);
// ignore errors here by reason.

cout << "main coro finishes\n";
});

io.run ();
}

坦率地说,我不喜欢这个解决方案,因为它滥用了“计时器”的概念和对象,并且可能浪费系统资源。

关于c++ - 如何等待所有 boost 完成 :asio's stackful coroutines?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26483749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com