一、协程基础概念解析
1.1 什么是协程?
协程(Coroutine)是一种用户态轻量级线程,允许在多个执行上下文之间进行协作式切换。与操作系统管理的线程不同,协程的调度完全由程序控制,具有以下核心特征:
- 协作式调度:主动让出执行权(非抢占)
- 状态保持:挂起时自动保存局部变量
- 高效切换:无内核态切换开销
1.2 协程分类体系
C++20采用无栈协程(Stackless Coroutine)方案,通过状态机转换实现协程切换。与传统线程相比,协程切换成本极低(约纳秒级),且完全由程序控制。
特性 | 有栈协程 | 无栈协程(C++20采用) |
---|---|---|
内存占用 | 每个协程独立栈(通常MB级) | 共享栈(KB级) |
切换开销 | 较高(需要切换栈指针) | 极低(仅修改状态机) |
挂起深度 | 支持任意嵌套挂起 | 只能在顶层函数挂起 |
典型代表 | Go goroutine, Lua协程 | C# async/await, Python生成器 |
1.3 协程生命周期
Coroutine -> 创建 -> 挂起点 -> 挂起 -> 恢复 -> 完成
1.4 三大关键字语义
co_await
:表达式求值流程
a) 检查await_ready()
b) 若未就绪,挂起并注册恢复回调
c) 恢复时调用await_resume()
co_yield
:等价于
co_await promise.yield_value(expr);
co_return
:触发promise
的return_void/value
或return_error
二、协程典型应用场景
2.1 生成器(Generator)
Generator<int> range(int start, int end) {for(int i=start; i<=end; ++i) {co_yield i; // 保持循环状态}
}
2.2 异步I/O操作
async_task<void> http_request() {auto data = co_await async_download(url); // 非阻塞等待process(data);
}
2.3 状态机实现
StateMachine create_parser() {while(true) {switch(current_state) {case HEADER:if(co_await read_byte() == 0x0A)current_state = BODY;break;case BODY:// 解析消息体逻辑break;}}
}
2.4 游戏开发(行为树)
async_task<void> enemy_ai() {while(enemy_alive) {co_await patrol_area(); // 巡逻行为if(player_visible) {co_await chase_player(); // 追击行为}}
}