C++20 特性 协程 Coroutines(1)

C++20 特性 协程 Coroutines(1)攻略

协程是C++20新增的一种编程语言特性,可用于异步编程,可以替代传统的回调、线程等异步编程方式,用于解决利用多核CPU或者异步I/O时出现的瓶颈,提高应用程序的性能。

协程的概述

协程是指一种在函数中使用的、可以在执行中暂停和继续的计算机程序组件。简单的说,协程就是可以在函数内通过暂停/恢复来提高程序性能的一种编程语言特性。

协程有两个关键的操作:暂停和恢复。暂停时将函数的状态保存下来并退出,等到再次调用时再恢复保存的状态并继续执行下去。通过这种方式实现了在函数内部建立一个事件循环,通过简单地暂停/恢复来实现“协作式多任务处理”。

协程的基本语法

在C++中,协程通过co_awaitco_yield关键字来实现。其中co_await用于等待协程的执行结果,co_yield用于将控制权交回给调用者并返回执行结果。

#include <coroutine>
#include <iostream>

class Generator {
public:
    struct promise_type;   //coroutine需要的类型
    using handle_type = std::coroutine_handle<promise_type>;  //协程句柄

    Generator(handle_type h)
        : handle_(h)
    {
    }

    Generator(const Generator&) = delete;
    Generator(Generator&& other) noexcept //移动构造函数
        : handle_(other.handle_)
    {
        other.handle_ = nullptr;
    }

    ~Generator()
    {
        if (handle_)
            handle_.destroy();  //销毁协程
    }

    Generator& operator=(const Generator&) = delete;
    Generator& operator=(Generator&& other) noexcept
    {
        if (this != &other) {
            if (handle_)
                handle_.destroy();
            handle_ = other.handle_;
            other.handle_ = nullptr;
        }
        return *this;
    }

    int operator()()
    {
        handle_.resume();   //通过resume函数开始执行协程
        return handle_.promise().current_value;   //返回当前协程的值
    }

private:
    handle_type handle_;
};

struct Generator::promise_type {
    int current_value;

    Generator get_return_object()
    {
        return Generator{ handle_type::from_promise(*this) };  //获得协程句柄
    }
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() { return std::suspend_always{}; }

    void unhandled_exception() { std::terminate(); } //应对异常
    std::suspend_always yield_value(int value)   //协程执行过程中,通过yield_value交还当前值
    {
        current_value = value;
        return {};
    }
};

Generator cofunc()
{
    co_yield 1; // 协程的第一次,即第一个数
    co_yield 2; // 第二个数
    co_yield 3; // 第三个数
}

int main()
{
    Generator g = cofunc();
    std::cout << g() << std::endl; // 输出 1
    std::cout << g() << std::endl; // 输出 2
    std::cout << g() << std::endl; // 输出 3
    return 0;
}

在main函数中通过Generator cofunc()来获得一个协程句柄,通过该句柄可以通过调用()来执行协程,执行过程中调用co_yield交回控制权,返回执行结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++20 特性 协程 Coroutines(1) - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++实现一个简单的线程池的示例代码

    下面是实现简单线程池的代码攻略。 什么是线程池? 线程池是一种用于管理多线程执行的机制,允许在需要时提供可分配的工作线程集中的线程。使用线程池的好处是可以减少线程的创建和销毁次数,避免线程频繁创建和销毁所带来的开销,也可以避免同时开启大量的线程造成系统资源的过度占用。在实际生产环境中,线程池通常具有限制线程数量、任务队列、线程管理等功能。 C++实现线程池的…

    C 2023年5月24日
    00
  • 用C语言实现圣诞树(简易版+进阶版)

    用C语言实现圣诞树(简易版) 1. 简介 该项目是使用C语言编写的简易版圣诞树,主要运用了printf函数的格式控制符,实现了树干和树叶的绘制,以及使用循环控制结构来控制树叶的数量。 2. 实现过程 2.1 绘制树干 树干的绘制使用printf函数实现,主要通过使用空格和竖线符(“|”)来实现。具体实现代码如下: printf(" |\n&quot…

    C 2023年5月23日
    00
  • Windows OpenGL ES 图像 GPUImageAmatorkaFilter

    零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 特效 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES …

    C语言 2023年4月18日
    00
  • win10中0x40000015是什么错误? 0x40000015错误代码的解决办法

    Win10中0x40000015是什么错误?0x40000015错误代码的解决办法 在使用Windows 10时,有时会出现0x40000015错误代码,这是一种Windows操作系统的错误,通常与某些系统文件或设备驱动程序有关。在这篇文章中,将为您介绍0x40000015错误的含义以及解决办法。 错误含义 0x40000015错误指的是Windows操作系…

    C 2023年5月23日
    00
  • 一文带你学习C++析构函数

    一文带你学习C++析构函数 什么是析构函数 析构函数是C++中的一种特殊函数,在对象被销毁时自动执行,用于清理对象所占用的内存和资源。 析构函数的特点 析构函数没有参数和返回值 析构函数名前需加波浪线( ~)以区分于构造函数 析构函数声明在类中,实现在类外 自动调用,不可显式调用 析构函数的语法 ~ClassName(){ //析构函数体 } 示例一:在析构…

    C 2023年5月22日
    00
  • 关于 Python json中load和loads区别

    关于 Python json中load和loads区别 在Python中使用Json模块解析Json时,经常会用到json.load()和json.loads(),这两个方法都可以将Json格式的字符串转化为Python能够识别的对象,但是它们却有一定的区别。 1. json.load() json.load()方法可以从一个文件对象中读取数据,并将其解析为…

    C 2023年5月23日
    00
  • JDK 7 新特性小结实例代码解析

    JDK 7 新特性小结实例代码解析 简介 JDK 7 是 Java Development Kit 的版本号,是 Java 的一个版本。JDK 7 主要添加了许多新特性,包括小型语言改进、文件访问/输入和输出的 I/O 改进、内部脚本引擎、实例创建类型推断、字符串开头的结尾和 switch 语句中的字符串变量、数字下划线等。本文将从例子出发,详细地介绍 JD…

    C 2023年5月23日
    00
  • C++中rapidjson将map转为json的方法

    将map转为json是一个常见的需求,在C++中,可以通过rapidjson库来实现。以下是具体的方法: 引入rapidjson头文件: #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" 创建rapidjson的字符串缓冲区: rapid…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部