C++20 协程:异步编程新范式
理解协程的基本概念、co_await、co_yield和co_return的用法,并构建简单的生成器。 · 难度:入门 · +15XP
协程简介
C++20协程是一种可暂停和恢复的函数,无需线程切换即可实现异步。协程通过三个新关键字实现:co_await、co_yield和co_return。
协程的基本结构
一个协程必须包含一个承诺对象(promise type)和一个可等待体(awaitable)。最简单的例子是生成器。
#include <coroutine>
#include <iostream>
#include <exception>
struct Generator {
struct promise_type {
int current_value;
std::suspend_always yield_value(int value) {
current_value = value;
return {};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
Generator get_return_object() { return Generator{this}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
using handle_type = std::coroutine_handle<promise_type>;
handle_type coro;
explicit Generator(promise_type* p) : coro(handle_type::from_promise(*p)) {}
~Generator() { if (coro) coro.destroy(); }
bool next() {
coro.resume();
return !coro.done();
}
int value() { return coro.promise().current_value; }
};
Generator range(int start, int end) {
for (int i = start; i < end; ++i)
co_yield i;
}
int main() {
auto gen = range(1, 5);
while (gen.next())
std::cout << gen.value() << ' ';
}
co_await 与可等待体
co_await用于暂停协程直到某个操作完成。标准库提供std::suspend_always和std::suspend_never。
练习提示
修改上述生成器,使其支持co_yield输出斐波那契数列的前N项。注意管理协程句柄的生命周期。