协程(coroutine)是 C++20 标准中加入的一项强大功能,它让编写异步代码变得更直观、更易维护。相比传统的回调、Promise/Future 或线程模型,协程通过 co_await、co_yield 和 co_return 三个关键字,将异步逻辑与同步代码的风格融合在一起,极大简化了错误处理、状态管理以及资源释放等方面的复杂度。
1. 协程的基本概念
协程本质上是可以挂起(suspend)并在之后恢复执行的函数。它们的执行过程由编译器自动生成的状态机来控制。协程分为三类:
generator:通过co_yield产生值,类似于迭代器;task:异步任务,使用co_await等待异步操作完成;producer/consumer:在多协程环境下实现生产者与消费者模式。
协程的核心是 promise object,负责协程的生命周期管理和异常处理。co_await 的被等待对象必须实现 await_ready(), await_suspend(), await_resume() 这三个成员函数。
2. 协程与标准库
C++20 标准库提供了一些基础协程类型,例如 `std::generator
`、`std::future`(已改为异步协程友好版本)以及 `std::task`。标准库还提供了 `std::experimental::coroutine_handle` 用于手动控制协程的执行和销毁。 “`cpp #include #include #include #include struct Timer { std::chrono::milliseconds duration; struct awaitable { std::chrono::milliseconds duration; bool await_ready() const noexcept { return false; } void await_suspend(std::coroutine_handle h) const noexcept { std::thread([h, d=duration]{ std::this_thread::sleep_for(d); h.resume(); }).detach(); } void await_resume() const noexcept {} }; awaitable operator co_await() const { return awaitable{duration}; } }; std::generator countdown(int start) { for (int i = start; i >= 0; –i) { co_yield i; } } auto async_task() -> std::future { std::cout handle_client(tcp::socket socket) { std::string data; while (co_await socket.async_read_some(asio::buffer(data), asio::use_awaitable)) { co_await socket.async_write_some(asio::buffer(data), asio::use_awaitable); } } “` ### 3.2 并发任务调度 协程可以轻松实现任务调度器。通过维护一个协程队列,调度器在协程挂起时切换到其他协程,从而实现轻量级并发。 “`cpp class Scheduler { std::vector> tasks; public: void add(std::coroutine_handle h) { tasks.push_back(h); } void run() { while (!tasks.empty()) { auto h = tasks.back(); tasks.pop_back(); h.resume(); if (h.done()) h.destroy(); else tasks.push_back(h); } } }; “` ## 4. 性能与限制 协程本身并不引入额外的线程开销,所有挂起与恢复均在同一线程完成(除非你显式在 `await_suspend` 中切换线程)。但由于协程生成的状态机可能占用一定栈空间,需要合理规划协程体的大小。C++20 协程的实现目前在不同编译器中性能差异不大,但在高频调用场景下仍需关注生成器的抛弃策略与异常路径。 ## 5. 未来展望 C++23 对协程的进一步改进主要集中在 **任务类型**(`std::task `)和 **协程上下文**(`std::context`)上,预计将提供更完善的异常传播、超时支持与资源管理。此外,社区正在研究 **协程适配器**,使得传统的异步 API(如 `std::future`、`std::promise`)可以无缝转换为协程。 ## 结语 协程的引入大大降低了 C++ 异步编程的门槛,让开发者可以用同步式思维书写并发逻辑。随着标准库和第三方框架的完善,协程将成为 C++ 高性能系统编程不可或缺的工具。掌握协程的使用方式,将为你的项目带来更清晰的代码结构和更优的运行效率。