C++20协程通过co_await、co_yield、co_return关键字实现函数暂停与恢复,核心组件包括promise_type、coroutine_handle和awaitable对象。示例展示协程创建、暂停及通过句柄恢复执行,适用于异步编程如网络请求,提升代码可读性与效率。

协程(Coroutine)是C++20引入的重要特性,它允许函数在执行过程中暂停并恢复,非常适合处理异步操作,比如网络请求、文件读写等。与线程不同,协程是用户态的轻量级执行单元,开销更小,调度更灵活。
理解C++协程的基本概念
C++中的协程不是像Python那样通过关键字直接定义,而是通过编译器识别特定函数形式来启用。一个函数只要使用了co_await、co_yield 或 co_return,就会被当作协程处理。
协程的核心组件包括:
-
Promise Type:控制协程的行为,如返回值、异常处理和暂停逻辑
-
Coroutine Handle:用于手动管理协程的生命周期和恢复执行
-
Awaitable/Awaiter:定义可等待对象的行为,决定何时暂停或继续
这些机制由编译器自动生成框架,开发者需要实现部分接口以满足需求。
立即学习“C++免费学习笔记(深入)”;
实现一个简单的协程示例
下面是一个最简化的协程例子,展示如何创建并运行一个可暂停的协程:
#include <coroutine>
#include <iostream>
struct SimpleTask {
struct promise_type {
SimpleTask get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
SimpleTask hello_coroutine() {
std::cout << "Hello from coroutine\n";
co_await std::suspend_always{};
std::cout << "Resumed coroutine\n";
}
int main() {
auto coro = hello_coroutine();
// 协程已经执行到 co_await 处暂停
// 这里可以做其他事情
return 0;
}
在这个例子中,hello_coroutine 函数开始执行后打印第一行,然后遇到 co_await std::suspend_always{} 暂停。但由于我们没有保存协程句柄,也无法恢复它,所以第二条输出不会被执行。
如何恢复协程执行
要真正控制协程的暂停与恢复,需要用到 std::coroutine_handle。修改上面的例子,加入句柄管理:
#include <coroutine>
#include <iostream>
struct ResumableTask {
struct promise_type {
ResumableTask get_return_object() {
return {std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
std::coroutine_handle<promise_type> h_;
explicit ResumableTask(std::coroutine_handle<promise_type> h) : h_(h) {}
~ResumableTask() { if (h_) h_.destroy(); }
void resume() { if (h_ && !h_.done()) h_.resume(); }
};
ResumableTask my_coroutine() {
std::cout << "Started\n";
co_await std::suspend_always{};
std::cout << "Resumed\n";
}
int main() {
auto t = my_coroutine(); // 创建协程,但尚未运行
t.resume(); // 第一次恢复:输出 "Started"
t.resume(); // 第二次恢复:输出 "Resumed"
return 0;
}
这次我们通过 get_return_object() 返回包含句柄的对象,并提供 resume() 方法来主动恢复执行。注意 initial_suspend 设置为 suspend_always,确保协程创建后处于暂停状态,直到手动恢复。
协程在异步编程中的应用思路
协程真正的价值体现在异步编程中。设想一个网络请求场景:传统回调方式容易导致“回调地狱”,而协程可以让异步代码看起来像同步一样清晰。
例如,可以设计一个可等待的 future 类型:
- 当数据未就绪时,协程自动挂起
- IO 完成后通过回调唤醒协程继续执行
- 使用 co_await 直接获取结果,无需嵌套 lambda
虽然标准库目前对高层异步支持有限,但像 cppcoro 或 Boost.Asio 等第三方库已提供成熟的异步协程工具集。
基本上就这些。掌握协程的关键在于理解其状态机本质和生命周期管理。从简单任务开始,逐步构建对 promise、awaiter 和调度的理解,才能真正用好C++协程进行高效异步开发。
以上就是C++如何实现一个简单的协程_C++协程基础与异步编程实现的详细内容,更多请关注php中文网其它相关文章!