c++基础语法之future,promise,async详细讲解-SurfaceFlinger学习必备c++知识

c++11多线程编程(八):std::future , std::promise和线程的返回值 std::future对象可以和asych,std::packaged_task,std::promise一起使用。这篇文章集中讨论std::future和std::promise。 我们经常会遇到需要得到线程返回结果的情况,现在的问题是我们如何实现。 举个例子: 假设在程序中,我们创建了一个压缩给定文件夹的线程,并且我们希望该线程能够返回新的zip文件的名称和大小。 有两种实现方式: 阅读详情

hi,粉丝朋友们:

背景

在开始学习SurfaceFlinger相关源码分析时候,发现也有大量的新语法,这里如果需要顺利看懂代码就不得不学习一些新版本c++基础语法。比如看到如下的drawLayers这个方法时候,当时trace中看到是有线程切换,这里代码我们看到是future和promise。
在这里插入图片描述

在这里插入图片描述trace可以看出来有线程切换和等待
在这里插入图片描述
为啥新版本要出现std::future和std::promise呢?
以前版本创建了线程以后,我们不能直接从thread.join()得到结果,必须定义一个变量,在线程执行时,对这个变量赋值,然后其他线程执行join()等待线程执行完成,再获取这个值,过程相对繁琐。
  thread库提供了future用来访问异步操作的结果。std::promise用来包装一个值将数据和future绑定起来,为获取线程函数中的某个值提供便利,取值是间接通过promise内部提供的future来获取的,也就是说promise的层次比future高。

future

官方解释参考地址:
https://legacy.cplusplus.com/reference/future/future/?kw=future
获取线程返回值的类std::future,用来访问异步操作的结果。因为异步操作需要时间,future并不能马上获取其结果,只能在未来某个时候获取期待值,因此被称为future。
可以通过同步等待的方式,通过查询future的状态(future_status),来获取异步操作的结果。

future_status状态有3种:
1)future_status::deferred 异步操作还没开始;
2)future_status::ready 异步操作已经完成;
3)future_status::timeout 异步操作超时;

获取future异步操作的结果,有4种方式:
1)get 等待异步结束并返回结果;
2)wait 只是等待异步操作结束,没有返回值;
3)wait_for 超时等待异步操作返回结果,注意这里的返回结果就是future_status
4)wait_until 等待达到指定的时间点,异步操作返回结果,常配合当前时间点 + 时间段来设置目标时间点;

平常开发中使用get最多,因为一般使用future是想要获取另一个线程的执行结果,一般不会单独使用这个future类,会结合async和promise一起使用

async

std::async,线程异步操作函数std::async,可用来创建异步task,其返回结果保存到future对象中。当需要取得异步结果时,调用future.get()即可。如果不关注结果,只是简单等任务完成,可以使用future.wait()
方法原型,查询地址https://legacy.cplusplus.com/:

unspecified policy (1)	

template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>
    async (Fn&& fn, Args&&... args);

specific policy (2)	

template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>
    async (launch policy, Fn&& fn, Args&&... args);

在这里插入图片描述参数解释如上图所示
第一个核心参数的launch参数,代表线程创建的策略
1)std::launch::async 调用async时就开始创建线程;
2)std::launch::deferred 延迟加载方式创建线程。调用async时不创建线程,直到调用了future的get或者wait,才创建线程。
默认情况都是情况1
第二个是线程执行方法函数
第三个代表执行线程函数时候需要传递的参数

案例如下:

// async example
#include <iostream>       // std::cout
#include <future>         // std::async, std::future
#include <sys/types.h>
#include <unistd.h>
using namespace std;
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
  std::cout << "Calculating. Please, wait... thread Id = "<< gettid()<<endl;
  for (int i=2; i<x; ++i) if (x%i==0) return false;
  return true;
}
int main ()
{
  // call is_prime(313222313) asynchronously:
  std::future<bool> fut = std::async (is_prime,313222313);

  std::cout << "Checking whether 313222313 is prime main thread Id = "<< gettid()<<endl;
  // ...

  bool ret = fut.get();      // waits for is_prime to return

  if (ret) std::cout << "It is prime!\n";
  else std::cout << "It is not prime.\n";

  return 0;
}

执行结果如下:
在这里插入图片描述明显看到这里的调用async后就有两个线程了,主线程也是要等到子线程执行完成后才可以进行执行

promise

Promise
A promise is an object that can store a value of type T to be retrieved by a future object (possibly in another thread), offering a synchronization point.

On construction, promise objects are associated to a new shared state on which they can store either a value of type T or an exception derived from std::exception.

This shared state can be associated to a future object by calling member get_future. After the call, both objects share the same shared state:
- The promise object is the asynchronous provider and is expected to set a value for the shared state at some point.
- The future object is an asynchronous return object that can retrieve the value of the shared state, waiting for it to be ready, if necessary.

The lifetime of the shared state lasts at least until the last object with which it is associated releases it or is destroyed. Therefore it can survive the promise object that obtained it in the first place if associated also to a future.

协助线程赋值的类std::promise,将数据和future绑定。在线程函数中,为外面传入的promise对象赋值,线程函数执行完毕后,就可以通过promise的future获取该值。

应用场景

小疑问:为啥有了future这个后还需要promise呢?
这个问题回答其实可以考虑一下future的获取,future都是需要几个固定的异步线程调用方式,比如async这种,但是很多时候不喜欢用这种异步方式,那么自然也就没办法获取future,所以为了future的获取更加灵活方便,就需要有这个promise对象。

主要方法有
在这里插入图片描述

重点介绍如下两个常用的
1)get_future
用于返回一个和promise相关联的future对象,返回的这个future对象就可以调用相关get方法来获取promise通过se_value方法设置的值
2)set_value
设置promise的对应值

案例代码

#include <iostream>       // std::cout
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
using namespace std;
void print_int (std::future<int>& fut) {
  cout<<"child thread  print_int"<<endl;
  int x = fut.get();
  std::cout << "value: " << x << '\n';
}

int main ()
{
  std::promise<int> prom;                      // create promise

  std::future<int> fut = prom.get_future();    // engagement with future

  std::thread th1 (print_int, std::ref(fut));  // send future to new thread

  std::this_thread::sleep_for(std::chrono::seconds(1));
  cout<<"main thread  prom.set_value (10)"<<endl;
  prom.set_value (10);                         // fulfill promise
                                               // (synchronizes with getting the future)
  th1.join();
  return 0;
}

执行结果:
在这里插入图片描述
可以看到结果是子线程先打印了,执行到future.get会一直等待主线程进行set_value,才会继续往下执行,这里是不是相比前面async来说更加灵活,没有限制用啥多线程方式。

实战结合SurfaceFlinger剖析

构建好promise和对应future
在这里插入图片描述
主线程通过future的get进行等待子线程执行完成通过set_value
主线程等待:
在这里插入图片描述

子线程进行set_value部分

void SkiaGLRenderEngine::drawLayersInternal(
        const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
        const DisplaySettings& display, const std::vector<LayerSettings>& layers,
        const std::shared_ptr<ExternalTexture>& buffer, const bool /*useFramebufferCache*/,
        base::unique_fd&& bufferFence) {
//省略
    resultPromise->set_value({NO_ERROR, std::move(drawFence)});
    return;
}

通过上面学习基础知识这个sf的这块代码看起来是不是很方便了,学习了个新c++语法立马就结合SurfaceFlinger源码部分实战分析

再次贴上perfetto、systrace来再次结合验证

在这里插入图片描述
更多framework干货请关注“千里马学框架”

C++ 并发编程:std::promise/future、std::async、std:: packaged_task 1、std::promise 和 std::future future 和 promise 的作用是在不同线程之间传递数据,而且支持泛型的操作,使用起来更加方便。 使用 future 和 promise 在线程之间获取数据的机制又是什么呢? 假设线程 1 需要线程 2 的数据,则: 线程 1 初始化一个 promise 对象和一个 future 对象,promise 传递给线程2,相当于线程 2 对线程 1 的一个承诺;future 相当于一个接受一个承诺,用来获取未来线程 2 传递的值; 线程 2 获取 阅读详情

相关推荐

C++(11):多线程同步promise

promise用于在多个线程间传值,多用于一个线程执行到某个状态后,把自己的信息传递给另外一个线程(该线程在拿到这个信息前,会阻塞等待): #include <iostream> #include <thread> #include <future> #include <chrono> #include <functional> using namespace std; void init(promise<int> &p

风静如云的博客 1095

C++之std::promise

一、介绍 std::promise是C++11并发编程中常用的一个类,常配合std::future使用。std::promise提供了存储值的功能,这些值后来会通过std::promise对象创建的std::future对象异步获得。 注意:std::promise对象只能使用一次。 二、实例 在主函数(主线程)中声明 promise 及其对应的 future,在某个线程中传入 promise 并进行运算; 在另一个线程中出入 future, 可利用get得到前一个线程中计算的结果; #incl

sinat_31608641的博客 3151

华为无线AP+AC(ensp)

VLAN 100--192.168.100.0/24为AP的管理IP地址VLAN10--192.168.10.0/24为无线用户获取的IP地址在DHCP Server(LSW3)上查看地址分配情况。

abcdlalal的博客 1万+

C++中promise和future详解

C++中promise和future详解

weixin_45312249的博客 4811

2025年度工业级3D全景相机技术解析选型参考:国产品牌的技术突围与市场格局

本文分析了工业级3D相机在智慧城市和建筑数字化中的应用。通过对比国内外主流设备的技术参数和应用场景,发现国产品牌如众趣科技在性价比和本地化服务方面具有优势,尤其适合大型空间扫描项目;而国际品牌如Faro、Leica则在精度和可靠性上保持领先。建议根据项目需求(如测距范围、精度要求、预算)进行设备选型,综合考虑扫描效率、数据处理能力和系统兼容性。国产品牌已在国内大型基建项目中展现出竞争力,国际品牌则更适合高精度逆向工程和国际化项目。

gxdtgsy的博客 1072

一文读懂AI大模型时代的RAG技术

RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合检索技术与生成模型的技术架构,旨在通过动态引入外部知识库增强大语言模型(LLM)的生成能力。其核心思想是通过检索系统从外部数据源(如企业知识库、实时文档等)获取相关信息,并将检索结果作为上下文输入生成模型,以提高生成答案的准确性、时效性和专业性

awei0916的专栏 2119

C++ 11 多线程之promise

C++ 11 多线程之std::promise

索命的博客 2226

某易将军令口令纯算法还原py篇

算法开源,将军令口令算法。希望官方多多更新吧

任雪飘的博客 3909

c++ promise 使用详解

提供了存储值或者异常的机制,一般用于在一个线程中设置值或异常,并在另一个线程中获取这些值或异常

luohaha66的博客 889

【嵌入式 – GD32开发实战指南(ARM版本)】第1部分 基础篇 - 第1章 开发环境搭建

开发环境: MDK:Keil 5.30 MCU:GD32F207IK 1.1 GD32F207I-EVAL开发板简介 笔者使用的开发板是兆易创新设计的GD32F207I-EVAL开发板。 GD32F207I-EVAL开发板使用 GD32F207IK作为主控制器,主频120MHz、集成3MB Flash、256KB SRAM、通用定时器*10、Adv. TM*2、Basic TM*2、系统时钟*1、看门狗*2、RTC*1、USART*4、UART*4、I2C*3、SPI*3、I2S*1、SDIO*1、CAN

不问归期的博客 9989

coredump文件的原理是啥

Core Dump(核心转储)是操作系统在程序崩溃(如段错误、非法指令等)时自动生成的一个文件,它包含了程序崩溃瞬间的。通过 core dump,开发者可以像“时间回溯”一样检查程序崩溃瞬间的状态,是调试复杂问题的利器!终止时,Linux 内核会生成 core 文件。不会生成 core dump,因为它们是“优雅终止”信号。这样 core 文件会直接压缩存储,节省磁盘空间。的文件(类似可执行文件),可以用。Core 文件本质上是一个。

二进制君 383

C++ promise类

在异步编程中,可能会碰到这样的情况:比如创建了一个promise对象,然后在某个线程中通过get()访问它。然而,如果在调用get()之前,这个promise对象被析构(销毁),那个尝试获取结果的线程将会抛出std::future_error异常,其中error_code()将会返回std::future_errc::broken_promise。除此之外,可以使用智能指针(例如std::shared_ptr)来管理promise对象的生命周期,确保promise对象在最后一个引用被释放时才被删除。

qq_27898413的博客 1125

Qt应用软件【协议篇】自定义协议处理串口半包贴包

Qt串口数据,半包,贴包,丢包数据处理

小鱼酱的博客 1211

c++11 多线程之future和promise

td::future 和 std:: promise

weixin_44834554的博客 4765

Spring-AI 第 17 章 - 飞书机器人接入详解

✅ Stream 长连接(官方 SDK)✅ AI 对话(支持工具调用)✅ 消息接收与回复✅ 天气查询✅ 数据库查询✅ 数学计算✅ 事件去重Stream 长连接模式:使用官方 SDK 建立 WebSocket 长连接,服务器主动连接飞书,无需公网 IP消息处理流程:接收消息 → 解析内容 → AI 处理 → 回复用户AI 工具调用:接入 FunctionTools,支持天气、计算、日期、数据库查询等多种工具。

AppBlog.CN全栈架构 211

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C++之promise

可以存储一个【指定类型】的值并且可以通过std::future对象将值取出,主要用于多线程之间同步。std::promise对象主要用于给【shared state】设置一个值;std::future对象主要用于等待并获取【shared state】的值;【注意】:【shared state】主要用于存储【指定类型的值】或者【异常】,只要还有一个拥有【shared state】的对象(无论是std::promise或std::future对象),【shared state】都会存在。

ji2581072的博客 1114

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++11 异步编程(2)--- promise

std::promise是C++11引入的一个同步原语,它是异步编程工具集的一部分,与std::future配合使用,用于在线程之间传递值和同步操作。std::promise允许一个线程存储一个值或异常,该值或异常随后可以通过与之关联的std::future对象被另一个线程获取。这是一种线程间通信的机制。

weixin_45144862的博客 1310

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++异步编程(Promise 和 Future)

与c#(async/await)类似,c++ stl也提供类似的异步编程操作,如下文摘自ChatGPT,详细介绍了此类用法。C++11 引入了 Promise 和 FutureC++17 引入了 async/await语法在 C++11 中,和提供了一种线程间通信的方式。它们常用于一个线程(生产者)产生值,另一个线程(消费者)等待该值。这种机制被称为“承诺-未来”模式。

积累点滴,保持自我 1779

c++多线程之promise

std::promise是一个类模板,能够在某个线程中给它赋值,然后我们可以再其它线程中把这个值取出来。 下面是调用 下面是完整的代码: void testPromise(std::promise<int> &mypromise, int x) { cout << "x:" << x << endl; int nresult = 0; nresult = x + 10; nresult += 100; nresult -= 1; std

FairLikeSnow的博客 2801

future和promise的使用

future和promise的作用是在不同线程之间传递数据。使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问;而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要更改有关的接口,比较麻烦;promise支持泛型的操作,更加方便编程处理。 假设线程1需要线程2的数据,那么组合使用方式如下: 线程1初始化一个promise对象和一个future对象,promi...

鸟哥的博客 6824

C++ promise

【代码】C++ promise。

Kiris_king的博客 766

c++ 之future和promise

future和promise可以配合使用,主要作用是在不同线程间传递数据。举个简单例子,直接看代码: 从这个代码可以看到主线程中声明了一个p,然后通过p.get_future()将promise和future绑定。再将promise变量传到set_promise线程中,在set_promise线程中对promise赋值。然后就可以在主线程中通过future的get获取promise设置的值。 运行结果: 这里需要注意的一点是。如果set_promise线程迟迟没有对promise设置值,那主线程的futur

SWX230162的博客 2792

C++11多线程之promise

翻译了cppreference上关于promise的一些内容。

FinixLei的专栏 (https://github.com/FinixLei) 3122

【C++11】future和async等

C++11的future和async等关键字more。

慕雪华年的博客 2812

【C++多线程】promise

使用和一起实现一个线程。这个例子中,主线程会启动一个工作线程,工作线程计算一个结果,并通过promise将结果传递给future,然后主线程获取并打印结果。

m0_49106549的博客 887
上一篇: MirrorLayer可以正常触摸屏幕原理分析
下一篇: Ubuntu上VScode编译c++基础学习指南-SurfaceFlinger实战必备基础知识
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值