C++新特性 协程

本篇文章我们来讲述一下C++协程

协程(Coroutine)是一种能够挂起个恢复的函数过程  是一种轻量级的并发编程方式,也称为用户级线程。它与传统的线程(Thread)相比,具有更低的开销和更高的执行效率。 协程通常运用在异步调用中。

同步和异步 (拓展):同步是指线程要同时执行 如果没有两者没有同步 则需要线程A 等待线程B 或者主线程等待子线程  而异步编程就不需要线程的等待 但是也要注意线程争夺的问题 

协程要讲清楚非常的抽象和复杂 我们直接从实际入手

代码实例:

大家看完以上代码结果可能会有一点懵 这是什么? 这是怎么回事?下面 让我们来分析一下代码:

大家观察这段代码就知道 main函数创建了一个进程 进程里面创建了一个主线程  然后执行每个函数就是子线程  先进入bar()函数  先执行call bar 然后执行before bar 经过挂起点然后挂起  这时候一个线程跳出了bar函数 到main里面 另一个线程执行fool函数  fool函数执行完以后 再回到bar 函数里面继续执行 这就是本代码的大概思路

下面我们来介绍一下   co_return 和co_await

co_return :co_return 是 C++20 中引入的关键字,用于在协程中返回结果或结束协程。它用于替代 return 关键字,在协程函数中表示返回值,并触发协程的完成。

co_return代码实例:

#include <iostream>
#include <experimental/coroutine>

std::experimental::coroutine_handle<> myCoroutine;

void myTask() {
    std::cout << "Starting coroutine..." << std::endl;
    myCoroutine.resume(); // 启动协程
    std::cout << "Resuming execution..." << std::endl;
}

struct MyAwaitable {
    bool await_ready() const { return false; }
    void await_suspend(std::experimental::coroutine_handle<> handle) const {
        myCoroutine = handle; // 将当前协程保存起来
    }
    void await_resume() const {}
};

MyAwaitable asyncFunc() {
    std::cout << "Suspending execution..." << std::endl;
    co_await MyAwaitable{}; // 挂起协程,等待恢复
    std::cout << "Resumed execution..." << std::endl;
}

int main() {
    myTask();
    asyncFunc().await_resume();
    
    return 0;
}

在这个示例中,co_await 表达式会挂起 asyncFunc() 协程的执行,然后将控制权交还给 myTask() 协程。当我们调用 myCoroutine.resume() 时,asyncFunc() 的执行恢复,并继续执行后面的语句。

co_await介绍:

co_await 是 C++20 中引入的关键字,用于在协程中挂起当前的执行,并等待某个操作完成或者恢复执行。它是协程内部使用的一种语法,用于表示异步操作的等待。

在一个可暂停函数(协程)中,当遇到 co_await 表达式时,会发生以下几个步骤:

  1. 暂停当前协程的执行,并保存当前状态。
  2. 将控制权返回给调用方(如上层协程或者普通函数)。
  3. 在某个事件发生或者异步操作完成后,恢复之前保存的状态并继续执行。

具体来说,在使用 co_await 时需要满足两个条件:

  1. 表达式必须是一个可暂停的类型(也称为 Awaitable 类型),它要么定义了 bool await_ready() 方法来判断是否可以直接返回结果,要么定义了 void await_suspend(std::coroutine_handle<>) 方法和 void await_resume() 方法来进行挂起和恢复操作。
  2. 协程函数本身必须是异步上下文(比如异步任务、生成器)或者包含了异步操作。

代码实例:

#include <iostream>
#include <experimental/coroutine>

struct MyAwaitable {
    bool await_ready() const { return false; }
    void await_suspend(std::experimental::coroutine_handle<> handle) const {
        std::cout << "Suspending coroutine..." << std::endl;
        handle.resume(); // 恢复协程的执行
    }
    void await_resume() const {}
};

std::experimental::suspend_always asyncFunc() {
    std::cout << "Starting coroutine..." << std::endl;
    co_await MyAwaitable{}; // 使用 co_await 挂起协程
    std::cout << "Resuming execution..." << std::endl;
}

int main() {
    auto coro = asyncFunc();
    coro.resume(); // 启动协程
    
    return 0;
}

代码总结:在这个示例中,MyAwaitable 是一个自定义的可暂停类型,它定义了 bool await_ready() 方法void await_suspend(std::coroutine_handle<>) 方法来控制协程的挂起和恢复。当我们调用 co_await MyAwaitable{} 时,协程会被挂起,并且打印出相应的消息。然后通过 handle.resume() 来恢复协程的执行。

co_await实现对象:

co_await 来实现协程等待一个对象时,该对象需要满足特定的条件和接口。在 C++ 中,需要实现以下几个关键的部分:

  1. 实现 awaitable 类型:这是一个自定义的类型,表示可以被协程等待的对象。它需要定义 await_ready()await_suspend()await_resume() 这三个成员函数。

    • await_ready(): 返回一个 bool 值,表示对象是否已经准备好(即不需要暂停协程)。如果对象已经可用,则返回 true;否则返回 false。
    • await_suspend(): 返回一个指定异步操作完成后应该如何恢复协程执行的 awaiter 类型。
    • await_resume(): 返回异步操作结果的值。

代码实例:

#include <iostream>
#include <future>
#include <experimental/coroutine>

struct Awaitable {
    std::future<int> fut;

    bool await_ready() {
        return fut.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
    }

    void await_suspend(std::experimental::coroutine_handle<> handle) {
        fut.then([handle](std::future<int> f) mutable {
            // 异步操作完成后恢复协程执行
            handle.resume();
        });
    }

    int await_resume() {
        return fut.get();
    }
};

Awaitable makeAsyncRequest() {
    std::promise<int> p;
    auto fut = p.get_future();

    // 模拟异步操作
    std::thread([&p]() mutable {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        p.set_value(42);
    }).detach();

    return Awaitable{std::move(fut)};
}

std::experimental::suspend_always task() {
    auto result = co_await makeAsyncRequest(); // 等待异步操作完成,并获取结果
    std::cout << "Result: " << result << std::endl;
}

int main() {
   auto coro = task();
   coro.resume(); // 启动协程

   return 0;
}

总结:协程是应用于异步编程的一种方法 co_await函数用于当前的协程的挂起 这样可以更深层次的满足异步编程 要注意co_await函数的使用 co_return是用来返回结果和结束协程

好了 本篇内容就到这里 这篇文章可能有些难度 大家慢慢理解 

在这里小编想向大家推荐一个课程:https://xxetb.xetslk.com/s/2PjJ3T

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/368817.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫学习笔记-scrapy爬取汽车之家

1.终端运行scrapy startproject scrapy_carhome,创建项目 2.接口查找 3.终端cd到spiders,cd scrapy_carhome/scrapy_carhome/spiders,运行 scrapy genspider audi https://car.autohome.com.cn/price/brand-33.html 4.打开audi,编写代码,xpath获取页面车型价格列表 5.运行项目…

深度学习技巧应用35-L1正则化和L2正则在神经网络模型训练中的应用

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用35-L1 正则化和L2正则在神经网络模型训练中的应用。L1正则化和L2正则化是机器学习中常用的两种正则化方法,用于防止模型过拟合并提高模型的泛化能力。这两种正则化方法通过在损失函数中添加惩罚项来控制模型的复杂性。…

面试八股文(4)

文章目录 1.sleep和wait区别2.为什么调用start()方法会执行run()方法&#xff0c;为什么不能直接调用run()方法3.synchronized关键字4.并发编程的三个重要特性5.synchronized和volatile关键字区别6.ThreadLocal7.为什么要用线程池&#xff1f;8.实现Runnable接口和Callable接口…

课时13:变量基础_变量场景

2.1.1 变量场景 学习目标 这一节&#xff0c; 我们从 数据存储、变量场景、小结 三个方面来学习。 数据存储 数据存储 所谓的数据存储&#xff0c;我们从三方面来理解这句话&#xff1a;1、数据保存到哪里 -- 各种媒介&#xff0c;CPU、内存、磁盘、磁带、网盘...2、数据保…

react+ts+antd-mobile 动态tabs➕下拉加载

1.初始化项目 //搭建项目 npm create vitelatest react-jike-mobile -- --template react-ts//安装依赖 npm i //运行 npm run dev清理项目目录结构 安装ant design mobile ant design mobile是ant design家族里专门针对于移动端的组件库 npm install --save antd-mobile测试…

日志报错 git -c dif.mnemonicprefix=false -c core.guotepath=false 解决方法

前言: 在进行下面操作前,必须确保,你是否安装了Git。 查看Git 在命令行窗口中输入`git --version`: 如果这个命令成功显示了Git的版本信息,这表明Git已经被安装。 1. 使用Sourcetree SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端…

C++核心deque容器,stack容器,queue容器,list容器,set容器,pair ,map容器

3.deque容器 1.deque容器的基本概念 Vector容器是单向开口的连续内存空间&#xff0c;deque则是一种双向开口的连续线性空间。所谓的双向开口&#xff0c;意思是可以在头尾两端插入元素&#xff0c;但是在其头部操作效率奇差&#xff0c;无法被接受。 deque容器和vector容器最…

MongoDB索引详情

文章目录 MongoDB索引MongoDB索引数据结构WiredTiger数据文件在磁盘的存储结构 索引的分类索引设计原则索引操作创建索引查看索引删除索引 索引类型单键索引&#xff08;Single Field Indexes&#xff09;复合索引&#xff08;Compound Index&#xff09;多键索引&#xff08;M…

学成在线:采用XXL-JOB任务调度方案使用FFmpeg处理视频转码业务

分片技术方案 概述 XXL-JOB并不直接提供数据处理的功能&#xff0c;它只会给所有注册的执行器分配好分片序号&#xff0c;在向执行器下发任务调度的同时携带分片总数和当前分片序号等参数 设计作业分片方案保证多个执行器之间不会查询到重复的任务,保证任务不会重复执行 任…

机器学习-基础分类算法-KNN详解

KNN-k近邻算法 k-Nearest Neighbors 思想极度简单应用数学只是少效果好可以解释机器学习算法使用过程中的很多细节问题更完整的刻画机器学习应用的流程 创建简单测试用例 import numpy as np import matplotlib.pyplot as plt raw_data_X [[3.393533211, 2.331273381],[3.1…

Flutter实现轮播图功能

一、在pubspec.yaml中添加&#xff1a; dependencies:# 轮播图card_swiper: ^3.0.1card_swiper: ^3.0.1&#xff0c;要获取最新版本&#xff1a;https://pub-web.flutter-io.cn/packages/card_swiper/versions&#xff0c;这个里面有文档可以看&#xff0c;如下图&#xff1a;…

大模型ReAct智能体开发实战

哆啦A梦是很多人都熟悉的角色&#xff0c;包括我自己。 在成长过程中&#xff0c;我常常对他口袋里的许多小玩意感到惊讶&#xff0c;而且他知道何时使用它们。 随着大型语言模型 (LLM) 的发展趋势&#xff0c;你也可以构建一个具有相同行为方式的模型&#xff01; 我们将构建…

高中数学立体几何练习题3

用到的基础知识&#xff1a; 1. 2.

MATLAB计算多边形质心/矩心

前言&#xff1a;不规则四边形的中心 不规则四边形的出心有多种定义&#xff0c;以下是最常见的三种&#xff1a; 1.重心&#xff1a;重心是四边形内部所有顶点连线交点的平均位置。可以通过求解四个顶点坐标的平均值来找到重心。 2.质心&#xff1a;质心是四边形内部所有质点…

Python机器学习库(numpy库)

文章目录 Python机器学习库&#xff08;numpy库&#xff09;1. 数据的维度2. numpy基础知识2.1 numpy概述2.1 numpy概述2.1 numpy概述2.2 numpy库的引用 3. ndarray数组的创建3.1 N维数组对象ndarray3.2 创建ndarray数组3.2.1 使用Python列表、元组创建ndarray数组3.2.2 使用nu…

029 命令行传递参数

1.循环输出args字符串数组 public class D001 {public static void main(String[] args) {for (String arg : args) {System.out.println(arg);}} } 2.找打这个类的路径&#xff0c;打开cmd cmd C:\Users\Admin\IdeaProjects\JavaSE学习之路\scanner\src\com\yxm\demo 3. 编译…

Servlet+Ajax实现对数据的列表展示(极简入门)

目录 1.准备工作 1.数据库源&#xff08;这里以Mysql为例&#xff09; 2.映射实体类 3.模拟三层架构&#xff08;Dao、Service、Controller&#xff09; Dao接口 Dao实现 Service实现&#xff08;这里省略Service接口&#xff09; Controller层&#xff08;或叫Servlet层…

2024济南生物发酵展:会议日程安排和技术装备亮点预告

2024济南发酵展/2024生物发酵展/2024山东发酵展/2024济南生物制药展/2024生物技术展/2024食品设备展/2024食品加工展/2024济南细胞工程展 由中国生物发酵产业协会主办&#xff0c;上海信世展览服务有限公司承办的2024第12届国际生物发酵产品与技术装备展览会&#xff08;济南&a…

深入理解Istio服务网格数据平面Envoy

一、服务网格概述(service mesh) 在传统的微服务架构中&#xff0c;服务间的调用&#xff0c;业务代码需要考虑认证、熔断、服务发现等非业务能力&#xff0c;在某种程度上&#xff0c;表现出了一定的耦合性 服务网格追求高级别的服务流量治理能力&#xff0c;认证、熔断、服…

2023.12 淘天-数科 已offer

文章目录 岗位信息1面ld 12.17 1H2面 VP 12.18 40min3面 HR 12.2012.21offer薪资方案沟通 岗位信息 1面ld 12.17 1H &#xff08;是一个从业估计很长时间前辈&#xff0c;很平和&#xff0c;感觉能学到很多东西&#xff09; 自我介绍项目深究1.说下自己工作里最有成就感的事和…