cpp co
Coo test()
{
co_await ...
co_yield ...
co_return ..
}
当一个函数中出现co_await
,co_yield
,co_return
中任何一个时就被
当成协程处理。
协程必需要用户
定义类名为promise_type
的类,这个类名是固定的编译
器会在返回值类型中查找这个类Coo::promise_type
, 也就是promis_type
必需要定义在返回值Coo
类里面。
编译器还会创建一个coroutine handle
,通过这个handle就可以控制协程的恢愎执行与停止,它的类型是:std::coroutine_handle<promis_type>
这也是固定的。
编译器内部还会为协程创建一个state
用来保存协程的状态和局部变量
这此内部细节,用户无法感知。
以下是Coo的定义:
class Coo
{
public:
struct promise_type
{
Coo get_return_object() { return Coo(); }
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
}
协程执行
- 编译器实现创建 state 变量,把协程用到的变量保存到这个state中:值变量会调用copy或者move相关构造函数 引用变量保存引用不变。
- 创建
promise_type
对象实例 - 调用promise_type.get_return_object函数,这个函数的返回值就是协程的返回值
Coo
类型,编译器会把这个Coo实现保存到state中,当协程返回时
或者暂停时
就把这个Coo实承返回给调用者, - 调用
promise_type.initial_suspend
函数,这个函数返回值作用暂时不清楚 - 当执行到 co_await或者co_yield时,协程暂停,并返回前面
promise_type.get_return_object
函数创建的返回值Coo
。 - 当执行到
co_return
时: -
- 如果
co_return
没有返回参数,则调用promise_type.return_void()
- 如果
coreturn
有返回参数比如co_return 11
则调用promise_type.return_value(11)
- 删除所有协程创建的变量
- 调用
promise_type.final_suspend()
and co_wait the result 这里不太理解什么意思
- 如果
- 如果协程执行时产生了异常则调用
promise_type.unhandled_excception
再调用promise_type.final_suspend()
-
co_await
co_await暂时协程执行,返回到调用协程的地方
co_await expr;
如果定义了promise_type.await_transform(expr)
则会调用这个函数,变成这样:
auto wait_expr = promise_type.await_transform(expr)
co_await wait_expr
否则wait_expr就是expr本身
然后开始调用:
- wait_expr.await_ready(),如果这个函数返回false则调用wait_expr.await_suspend(handle)
- 如果await_suspend返回void则,协程返回到调用方并暂停执行
- 如果await_suspend返回true,协程返回到调用方并暂停执行
- 如果await_suspend返回false,则resume当前协程
- 如果await_suspend返回handle,则调用handle.resume执行handle协程 -
- 最后调用wait_expr.await_resume(),它的返回值就是co_await expr的结果。
co_yield
co_yield expr
待价于co_await promise_type.yield_value(expr)