c++20协程是什么 c++ coroutine入门使用【前沿】
#技术教程 发布时间: 2025-12-25
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 是协程行为的“控制中心”,至少需实现:
-
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 << "st
art\n";
co_await std::suspend_always{}; // 主动挂起一次
std::cout << "resumed\n";
co_return;
}
调用后协程立即执行到 co_await 挂起;之后需手动调用 coroutine_handle::resume() 才会继续——这就是“可控暂停”的本质。
上一篇 : 《告别回忆 双想 Break out of my shell》初回特典小游戏OP
下一篇 : 村落人生竹篮获取方法
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!
art\n";
co_await std::suspend_always{}; // 主动挂起一次
std::cout << "resumed\n";
co_return;
}