我目前正在
task_sub()
函数的开头创建多个task_main()
,并等待这些task_sub()
结束后再退出task_main()
。只有一个线程。我该怎么办?
有什么办法可以达到这个要求吗?注意:
task_main()
和task_sub()
不在同一级别,task_sub()
必须在task_main()
中创建。
asio 1.31.0
awaitable<void> task_sub()
{
// TODO something
}
awaitable<void> task_main()
{
printf("task_main begin\n");
// create some task_sub and execute
auto task1 = co_spawn(co_await this_coro::executor, task_sub(), xxxxxx?);
auto task2 = co_spawn(co_await this_coro::executor, task_sub(), xxxxxx?);
// main loop
// TODO something
// waiting task
co_await task1;
co_await task2;
printf("task_main end\n");
}
我尝试过使用
use_future
等待任务结束,但它不支持co_await
并且task1.wait()
是同步和阻塞的,这会阻塞主循环。
awaitable<void> task_main()
{
printf("task_main begin\n");
// create some task_sub and execute
//
std::future<void> task1 = co_spawn(co_await this_coro::executor, task_sub(), use_future);
std::future<void> task2 = co_spawn(co_await this_coro::executor, task_sub(), use_future);
// main loop
// TODO something
// waiting task
//co_await task1;
//co_await task2;
//is blocked
task1.wait();
task2.wait();
printf("task_main end\n");
}
我也尝试过使用
channel
,可以用,但是不太漂亮
//...
#include <asio/experimental/channel.hpp>
using exit_channel = asio::experimental::channel<void(asio::error_code)>;
awaitable<void> task_sub(exit_channel& channel)
{
// TODO something
//end
co_await channel.async_send(error_code{});
}
awaitable<void> task_main()
{
printf("task_main begin\n");
auto ctx = co_await this_coro::executor;
// create some task_sub and execute
exit_channel task1_channel(ctx, 1);
exit_channel task2_channel(ctx, 1);
co_spawn(ctx, task_sub(task1_channel), detached);
co_spawn(ctx, task_sub(task2_channel), detached);
// main loop
// TODO something
// waiting task
co_await task1_channel.async_receive();
co_await task2_channel.async_receive();
printf("task_main end\n");
}
而且
co_spawn(,,use_awaitable)
,它不会在co_spawn
开始执行,所以这不是你想要的。
就像我之前回答您删除的问题一样,您可以使用
use_promise
:
#include <asio.hpp>
#include <asio/experimental/promise.hpp>
#include <asio/experimental/use_promise.hpp>
#include <stdio.h>
using asio::awaitable;
using asio::experimental::use_promise;
using namespace std::chrono_literals;
namespace this_coro = asio::this_coro;
awaitable<void> delay(auto dur) {
co_await asio::steady_timer{co_await this_coro::executor, dur}.async_wait();
}
awaitable<void> task_sub(char const* caption, int n, auto ival) {
for (int i = 0; i < n; ++i) {
printf("task_sub '%s' %d\n", caption, i);
co_await delay(ival);
}
}
awaitable<void> task_main()
{
printf("task_main begin\n");
auto ex = co_await this_coro::executor;
// create some task_sub and execute
auto task1 = co_spawn(ex, task_sub("task1", 5, 500ms), use_promise);
auto task2 = co_spawn(ex, task_sub("task2", 4, 750ms), use_promise);
// main loop
// TODO something
co_await task_sub("task_main", 3, 1000ms);
printf("task_main wait\n");
co_await std::move(task1);
co_await std::move(task2);
printf("task_main end\n");
}
int main() {
asio::io_context ctx;
co_spawn(ctx, task_main(), asio::detached);
ctx.run();
}
观看直播:
¹ 在线使用 Boost Asio,因为它没有独立的 Asio