C++20正式将协程纳入标准库,为异步编程带来了巨大改变。协程允许函数在执行过程中暂停和恢复,避免了传统回调带来的嵌套和状态管理难题。借助编译器支持的几个新关键字,我们可以用接近同步的风格编写异步逻辑。

协程的基础概念
在C++中,协程是一种可以挂起和恢复的函数。与普通函数不同,协程通过co_await、co_yield和co_return来控制流程。一个函数只要包含了这三个关键字之一,就会被编译器当作协程处理。
- co_await:暂停协程,等待某个异步操作完成。
- co_yield:产生一个值并挂起,常用于生成器。
- co_return:结束协程并返回结果。
一个简单的生成器协程
下面示例展示如何用协程实现一个整数序列生成器。我们使用标准库的std::generator(需要包含<generator>头文件,部分编译器需实验性支持)。
#include <coroutine>
#include <generator>
#include <iostream>
// 使用C++23的std::generator,若在C++20下可用实验性实现
std::generator<int> count_to(int n) {
for (int i = 1; i <= n; ++i) {
co_yield i; // 每次产生一个值并挂起
}
}
int main() {
for (int v : count_to(5)) {
std::cout << v << " ";
}
std::cout << std::endl;
return 0;
}
上述代码中,count_to是一个协程函数,通过co_yield逐个返回数字。调用时并不会一次性算完,而是每次循环取一个值,体现了懒执行特性。
异步任务中的co_await
在真实异步场景里,我们常用co_await等待IO或定时任务。下面伪代码展示基本结构:
#include <chrono>
#include <thread>
#include <coroutine>
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
Task async_work() {
// 模拟异步等待
co_await std::suspend_always{};
// 实际中可等待网络或文件IO完成
co_return;
}
总结
C++20协程通过语言级支持简化了异步编程模型。理解co_await、co_yield以及承诺对象(promise_type)是掌握协程的关键。随着编译器支持完善,协程将成为现代C++开发的重要工具。