C++20协程是编译器支持的协作式执行机制,通过co_await、co_yield、co_return识别,需自定义返回类型及promise_type,并遵循awaiter协议实现挂起与恢复。

C++20协程不是“线程”或“语法糖”,而是一套编译器支持的、用户可定制的协作式执行机制。它让函数能中途暂停、保存状态、稍后从中断点恢复,整个过程不依赖操作系统调度,开销远低于线程,也比回调嵌套更直观。
协程怎么识别?三个关键字就够了
只要函数体内出现以下任意一个,编译器就把它当作协程:
- co_await:挂起当前协程,等待某个操作完成(比如网络响应、定时器到期);
- co_yield:产出一个值并挂起,常用于生成器(如逐个返回斐波那契数);
- co_return:结束协程,并把结果交给调用方(可带值,也可不带)。
必须定义的返回类型和 promise_type
协程不能直接返回 int 或 void,必须返回一个自定义类型(如 task、generator),且该类型内部要嵌套定义 promise_type。
promise_type 是协程行为的“控制中心”,至少需实现:
立即学习“C++免费学习笔记(深入)”;
-
get_return_object():构造并返回协程句柄关联的对象(比如
task{handle}); -
initial_suspend():决定协程一启动就运行(
suspend_never),还是先挂起(suspend_always); - final_suspend():协程结束时是否挂起(影响资源清理时机);
-
return_value(T) 或 return_void():接收
co_return的值; -
unhandled_exception():捕获未处理异常(建议调用
std::terminate或记录)。
co_await 背后是 awaiter 协议
co_await expr 不是直接等系统调用,而是要求 expr 类型满足 awaiter 接口:
- await_ready():快速判断是否还需真挂起(比如缓冲区已有数据,就跳过挂起);
- await_suspend(coroutine_handle):真正挂起时调用,通常注册回调(如投递到线程池、io_uring、epoll);
-
await_resume():恢复后执行,返回给
co_await表达式的值。
典型入门写法:一个最简 task
不用第三方库,也能跑通基本流程:
struct task {
struct promise_type {
task get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
};
task my_coro() {
std::cout << "start\n";
co_await std::suspend_always{}; // 主动挂起一次
std::cout << "resumed\n";
co_return;
}
调用后协程立即执行到 co_await 挂起;之后需手动调用 coroutine_handle::resume() 才会继续——这就是“可控暂停”的本质。











