协程(Coroutine)是 C++ 20 标准中引入的重要特性,它通过语法糖简化了异步编程、协作式多任务处理以及状态机的实现。本文从协程的概念入手,介绍关键语法,结合实际例子演示如何在 C++ 程序中实现协程,并讨论其优势与常见陷阱。
1. 协程概念回顾
协程是一种比线程更轻量级的计算单元,能够在运行时暂停(co_yield、co_await、co_return)并恢复,保持自己的局部状态。与线程不同,协程不需要上下文切换,调度由程序员控制,适合 I/O 密集型或需要频繁切换状态的场景。
2. C++ 20 协程的核心关键字
| 关键字 | 作用 |
|---|---|
co_await |
暂停协程直到 awaiter 结束,返回 awaiter 的结果 |
co_yield |
暂停协程并返回一个值给调用者,协程可以被继续执行 |
co_return |
结束协程,返回最终值 |
co_spawn |
(非标准,但在 Boost.Coroutine2 等库中使用)创建协程并调度运行 |
| `generator | |
| 在标准库中实现的生成器类型,用来包装使用co_yield` 的协程 |
3. 典型协程实现示例
下面给出一个简单的生成器例子,利用 `generator
` 生成从 1 到 N 的整数。 “`cpp #include #include #include // 需要 C++ 20 experimental/generator std::generator range(int start, int end) { for (int i = start; i #include #include struct TimerAwaiter { std::chrono::milliseconds duration; bool await_ready() const noexcept { return duration.count() == 0; } void await_suspend(std::coroutine_handle h) const noexcept { std::thread([h, dur = duration]() mutable { std::this_thread::sleep_for(dur); h.resume(); }).detach(); } void await_resume() const noexcept {} }; TimerAwaiter timer(std::chrono::milliseconds ms) { return TimerAwaiter{ms}; } std::generator timed_sequence() { for (int i = 0; i #include struct SimpleCoroutine { struct promise_type; using handle_type = std::coroutine_handle ; handle_type coro; SimpleCoroutine(handle_type h) : coro(h) {} ~SimpleCoroutine() { if (coro) coro.destroy(); } void resume() { if (!coro.done()) coro.resume(); } }; struct SimpleCoroutine::promise_type { auto get_return_object() { return SimpleCoroutine{handle_type::from_promise(*this)}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; SimpleCoroutine task() { std::cout