虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > C/C++编程 > C++ Coroutine简单学习教程

C++ Coroutine简单学习教程
类别:C/C++编程   作者:码皇   来源:互联网   点击:

这篇文章主要为大家详细介绍了C++ Coroutine的简单学习教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在C++里,一个函数如果其函数体实现中包含co_await、co_yield、co_return中任何一个关键字,那么这个函数就是一个coroutine。其中:

co_await:挂起当前的coroutine
co_return:从当前coroutine返回一个结果
co_yield:返回一个结果并且挂起当前的coroutine

一个coroutine要能被编译期识别并通过编译,在某些情况下要自己去特化coroutine_traits。下面就一个简单的coroutine来说一说C++编译器是如何修改这个coroutine的。

    // 我们假定这个模板函数是一个coroutinetemplate <typename TRet, typename … TArgs>TRet func(TArgs args…){
    body;
    // body里至少包含了co_await、co_yield、co_return三者之一。}

那么这个函数会被编译器改成如下形式:

    // 它会被编译期展开成如下形式template <typename TRet, typename ... TArgs>TRet func(TArgs args...){
    using promise_t = typename coroutine_traits<TRet, TArgs...>::promise_type;
    promise_t promise;
    auto __return__ = promise.get_return_object();
    // 这个__return__会被编译器特殊处理 co_await promise.initial_suspend();
    try {
    // co_return expr;
    => promise.return_value(expr);
    goto final_suspend;
    body;
    // co_return;
    => promise.return_void();
    goto final_suspend;
    }
    // co_yield expr;
    => co_await promise.yield_value(expr);
    catch (...) {
    promise.set_exception(std::current_exception());
    }
    final_suspend: co_await promise.final_suspend();
    }

以上是一个coroutine的基本形式。事实上看完之后会发现,一个coroutine的关键主要还是和其关联的promise。
和coroutine promise关联的另外一个概念,叫awaitable。Awaitable可以称为一个可等待对象。一个awaitable对象需要实现3个相关函数:

1、await_ready:awaitable实例是否已经ready

2、await_suspend:挂起awaitable。该函数会传入一个coroutine_handle类型的参数。这是一个由编译器生成的变量。suspend过程可以指定该coroutine何时何地以何种方式被resume。比方说实现suspend函数时,将coroutine_handle放到threadpool中。那么当前的coroutine接下来就运行在线程池指派的后台线程中运行了。

3、await_resume:当coroutine重新运行时,会调用该函数。

所以要让一个类型能够awaitable,有三种手段:

1、该类型相关代码无法修改时,需要实现:

bool await_ready(T &);
void await_suspend(T &, coroutine_handle<promise_type>);
auto await_resume(T &);  auto视具体情况而定

2、该类型相关代码可以修改时,需要增加3个成员函数:

bool await_ready();
void await_suspend(coroutine_handle<promise_type> ch);
auto await_resume();

3、实现operator co_await操作符,返回一个可等待的代理类型,并且实现了上述三个函数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关热词搜索: C++ Coroutine