• C++20 协程的使用


    1. 协程的概念

    • 协程(Coroutine)是一个可以暂停执行以便稍后恢复的函数。与线程和进程不同,协程在用户态进行切换,无需进入内核态,因此具有更高的执行效率。
    • C++20引入了协程的概念,并提供了相关的关键字和机制来支持协程编程。

    2. 关键字

    • co_await:用于暂停协程的执行,直到某个操作完成。
    • co_yield:用于暂停协程并返回一个值,通常用于生成器(generator)函数中。
    • co_return:用于结束协程的执行并返回一个值。

    3. 协程返回类型

    • C++20协程要求定义一个包含promise_type的类型,其中promise_type需要至少包含以下函数:
      • get_return_object:返回协程的返回对象。
      • initial_suspend:控制协程开始时的挂起行为。
      • final_suspend:控制协程结束时的挂起行为。
      • return_void:当协程返回void时调用。
      • unhandled_exception:当协程抛出未处理的异常时调用。
    • 常见的协程返回类型包括std::future或其他自定义类型。

    4. 使用示例

    • 协程函数通常包含co_awaitco_yieldco_return等关键字。
    • 协程的执行流程可以通过这些关键字进行控制,实现异步编程、生成器等复杂功能。

    5. 协程的优势

    • 协程切换在用户态进行,无需进入内核态,因此具有更高的执行效率。
    • 协程可以方便地处理异步I/O操作,避免阻塞和浪费资源。
    • 协程可以用于实现生成器等模式,简化代码结构,提高代码的可读性和可维护性。

    6.协程代码示例

    C++20引入了协程(Coroutines)的概念,它允许函数在挂起(suspend)和恢复(resume)之间切换,这对于异步编程和生成器等模式非常有用。

    首先,你需要一个协程返回类型(也称为promise类型),它负责协程的底层实现。在C++20中,你通常不需要直接定义这个类型,因为标准库提供了std::futurestd::generator(尽管std::generator不是标准库的一部分,但可以作为参考实现)这样的类型。然而,为了理解协程的工作原理,我们可以手动定义一个简单的promise类型。

    #include 
    #include 
    #include 
    #include  // 注意:std::generator 不是 C++20 标准的一部分
    
    // 自定义的promise类型(简化版)
    struct MyPromise {
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void unhandled_exception() { std::terminate(); }
    
        std::future<void> get_return_object() {
            auto promise = std::make_shared<std::promise<void>>();
            this->fut = promise->get_future();
            this->resolver = [promise = std::move(promise)]{
                promise->set_value();
            };
            return this->fut;
        }
    
        void return_void() {}
    
        std::future<void> fut;
        std::function<void()> resolver;
    };
    
    // 协程返回类型
    using MyCoroutine = std::experimental::coroutine_traits<MyPromise>::promise_type;
    
    // 协程函数
    MyCoroutine::promise_type::return_type my_coroutine() {
        co_await std::suspend_always{}; // 协程挂起点
        std::cout << "Coroutine body executing\n";
        co_return; // 协程返回点
    }
    
    int main() {
        // 启动协程(这里需要使用特殊的语法)
        auto coro = my_coroutine();
    
        // 等待协程完成
        coro.get_return_object().wait();
    
        std::cout << "Coroutine finished\n";
        return 0;
    }
    
    // 注意:上面的 std::experimental::generator 和 coroutine_traits 是为了示例而假定的
    // 在实际使用中,你可能需要使用其他库或自定义的协程类型
    

    注意

    1. std::experimental::generatorcoroutine_traits 并不是C++20标准的一部分。它们只是为了说明而使用的假想类型。在C++20中,你通常会使用std::future或自定义的promise类型来作为协程的返回类型。

    2. co_await 关键字用于挂起协程的执行,直到某个操作完成。在上面的示例中,我们使用了std::suspend_always,它只是简单地挂起协程而不等待任何条件。在实际应用中,你可能会挂起协程以等待I/O操作、网络请求或其他异步任务的完成。

    3. co_return 关键字用于结束协程的执行并返回一个值。在上面的示例中,我们没有返回任何值(即void),但你可以根据需要返回任何类型。

    4. 自定义的promise类型必须实现一些特定的成员函数,如initial_suspendfinal_suspendget_return_object等。这些函数控制协程的执行流程。

    5. C++20协程的具体实现可能因编译器和库的不同而有所差异。上述示例主要是为了演示协程的基本结构和用法,并不保证在所有编译器上都能正常工作。

  • 相关阅读:
    VsCode SSH远程设置不用重复输入密码
    SpringBoot学习笔记(六)——Redis数据库
    Java中static关键字
    脑电信号分类问题的数据预处理方法
    Python爬虫实战-小说网站爬虫开发
    使用记账软件记录生活收支明细,如何防止收支不被他人修改
    第一个 Go 程序“hello,world“ 与 main 函数
    相似度论文再回顾
    惊喜警报!Mini XMan线上快闪活动即将来袭!
    【JS】Chapter15-高阶技巧
  • 原文地址:https://blog.csdn.net/weixin_45717907/article/details/139391801