C++20协程是可挂起恢复的函数,需手动实现promise_type、awaiter和返回类型三要素;示例Generator通过co_yield实现懒加载整数生成,强调initial_suspend、final_suspend及生命周期管理。

协程不是线程,也不启动新执行流,它是一种可挂起、可恢复的函数,用于简化异步逻辑、生成器、状态机等场景。C++20 协程是语言级支持,但需要手动实现协程桩(promise type)、awaiter 和返回类型——不依赖运行时库,但也意味着不能直接“开箱即用”。
基础结构:三要素缺一不可
每个协程必须有:
-
返回类型:需定义
promise_type嵌套类,并提供get_return_object()、initial_suspend()、final_suspend()、return_void()(或return_value())等接口; -
挂起点:使用
co_await表达式,其操作数需满足 awaiter 要求(含await_ready()、await_suspend()、await_resume()); -
挂起关键词:
co_return(结束协程)、co_await(挂起等待)、co_yield(挂起并产出值,常用于 generator)。
最简可运行示例:一个懒加载的整数生成器
下面是一个能逐次产出 0、1、2 的协程 generator(类似 Python 的 yield):
// 编译需支持 C++20:g++-11+ / clang++-13+,加 -std=c++20 #include#include #include template struct Generator { struct promise_type; using handle_type = std::coroutine_handle struct promise_type { T current_value; auto get_return_object() { return Generator{handle_type::from_promise(*this)}; } auto initial_suspend() { return std::suspend_always{}; } auto final_suspend() noexcept { return std::suspend_always{}; } void return_void() {} void unhandled_exception() { std::terminate(); } auto yield_value(T value) { current_value = value; return std::suspend_always{}; } }; explicit Generator(handle_type h) : coro_(h) {} Generator(const Generator&) = delete; Generator& operator=(const Generator&) = delete; Generator(Generator&& rhs) noexcept : coro_(rhs.coro_) { rhs.coro_ = nullptr; } Generator& operator=(Generator&& rhs) noexcept { if (this != &rhs) { if (coro_) coro_.destroy(); coro_ = rhs.coro_; rhs.coro_ = nullptr; } return *this; } ~Generator() { if (coro_) coro_.destroy(); } bool next() { if (!coro_ || coro_.done()) return false; coro_.resume(); return !coro_.done(); } T value() const { return coro_.promise().current_value; } private: handle_type coro_; }; Generator counter() { co_yield 0; co_yield 1; co_yield 2; } int main() { auto g = counter(); while (g.next()) { std::cout << g.value() << '\n'; } // 输出:0\n1\n2 }
关键点说明
这段代码展示了协程最核心的协作模式:
《PHP设计模式》首先介绍了设计模式,讲述了设计模式的使用及重要性,并且详细说明了应用设计模式的场合。接下来,本书通过代码示例介绍了许多设计模式。最后,本书通过全面深入的案例分析说明了如何使用设计模式来计划新的应用程序,如何采用PHP语言编写这些模式,以及如何使用书中介绍的设计模式修正和重构已有的代码块。作者采用专业的、便于使用的格式来介绍相关的概念,自学成才的编程人员与经过更多正规培训的编程人员
立即学习“C++免费学习笔记(深入)”;
-
co_yield触发promise_type::yield_value(),保存值并挂起; -
Generator::next()调用resume()恢复执行,直到下次挂起或结束; -
initial_suspend()设为suspend_always,让协程创建后不自动运行(惰性求值); -
final_suspend()也设为suspend_always,防止协程结束后自动销毁 promise,方便外部安全读取结果。
常见误区提醒
初学容易踩坑的地方:
- 忘记在
~Generator中调用coro_.destroy()→ 内存泄漏; - 把协程句柄(
coroutine_handle)复制多次却不管理生命周期 → 悬空指针; - 误以为
co_await等价于“异步等待” → 它只是语法糖,行为完全由 awaiter 决定(可以立刻返回,也可以调度到线程池); - 没处理
unhandled_exception()→ 协程内抛异常会导致程序终止。
基本上就这些。协程本身不难理解,难点在于设计清晰的协程类型契约。建议从 generator 入手,再过渡到 async/await 风格的 task 类型(如 Task),逐步掌握 suspend/resume 的控制权。









