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)