当前位置: 首页 > news >正文

c++ std::future 和 std::promise 的实现工作原理简介

为了便于理解 std::futurestd::promise 的实现工作原理,我们可以创建一个简化的版本。这包括共享状态、Promise 设置值、Future 获取值的核心机制。我们的示例代码将实现 SimplePromiseSimpleFuture 两个类,二者通过一个共享状态实现线程间的通信和同步。

实现代码

1. 定义共享状态

共享状态是 PromiseFuture 之间共享的数据区域,用于存储值以及同步访问。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <optional>template <typename T>
class SharedState {
public:// 设置值void set_value(T value) {std::lock_guard<std::mutex> lock(mtx_);value_ = value;ready_ = true;cv_.notify_all();}// 获取值(阻塞直到值设置完成)T get_value() {std::unique_lock<std::mutex> lock(mtx_);cv_.wait(lock, [this] { return ready_; });return *value_;}private:std::mutex mtx_;std::condition_variable cv_;std::optional<T> value_;  // 使用optional来保存值(类似于指针,但更安全)bool ready_ = false;      // 表示是否设置了值
};
2. 实现 SimplePromise

SimplePromise 用于设置共享状态中的值。其主要功能包括创建共享状态实例,并在 set_value 中向状态中写入值。

template <typename T>
class SimplePromise {
public:SimplePromise() : state_(std::make_shared<SharedState<T>>()) {}// 设置值并通知 futurevoid set_value(T value) {state_->set_value(value);}// 获取 future 对象std::shared_ptr<SharedState<T>> get_state() {return state_;}private:std::shared_ptr<SharedState<T>> state_;
};
3. 实现 SimpleFuture

SimpleFuture 从共享状态中获取值,并在 get 中阻塞等待值设置完成。

template <typename T>
class SimpleFuture {
public:SimpleFuture(std::shared_ptr<SharedState<T>> state) : state_(state) {}// 获取值(会阻塞,直到值设置完成)T get() {return state_->get_value();}private:std::shared_ptr<SharedState<T>> state_;
};

4. 连接 SimplePromiseSimpleFuture

为了实现 std::promisestd::future 的连接,我们让 SimplePromise 创建共享状态实例,并通过该实例创建 SimpleFuture

template <typename T>
std::pair<SimplePromise<T>, SimpleFuture<T>> make_promise_future() {SimplePromise<T> promise;SimpleFuture<T> future(promise.get_state());return {promise, future};
}

使用示例

下面的示例展示了如何使用 SimplePromiseSimpleFuture 进行线程间的值传递。

int main() {// 创建 promise 和 futureauto [promise, future] = make_promise_future<int>();// 启动线程异步设置值std::thread t([&promise]() {std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟延迟promise.set_value(42);std::cout << "值已设置为 42" << std::endl;});// 主线程等待并获取结果std::cout << "等待结果..." << std::endl;int result = future.get();std::cout << "获取到结果: " << result << std::endl;t.join(); // 等待线程结束return 0;
}

代码流程解析

  1. 共享状态SharedState 负责存储值,set_value 在设置值后通知等待的线程,get_value 阻塞直到值被设置。
  2. SimplePromise:管理 SharedState 并设置值。
  3. SimpleFuture:等待并获取值。
  4. make_promise_future:帮助创建关联的 SimplePromiseSimpleFuture 对象。

工作流程图

+----------------+      +-------------------+       +----------------+
|   Thread 1     |      |   Shared State    |       |   Thread 2     |
+----------------+      +-------------------+       +----------------+
| SimplePromise  | ---> |  set_value(val)   | <---  | SimpleFuture   |
|                |      |   value = val     |       | get() blocking |
|   set_value(42)|      |  ready = true     |       | until ready    |
+----------------+      +-------------------+       +----------------+

总结

在这个实现中:

  • SimplePromise 通过共享状态的指针持有对共享状态的唯一引用。
  • SimpleFutureget 方法中阻塞,直到 SimplePromiseset_value 中通知共享状态已经就绪。
  • 共享状态通过条件变量和互斥锁确保线程安全,实现了异步值传递。

相关文章:

c++ std::future 和 std::promise 的实现工作原理简介

为了便于理解 std::future 和 std::promise 的实现工作原理&#xff0c;我们可以创建一个简化的版本。这包括共享状态、Promise 设置值、Future 获取值的核心机制。我们的示例代码将实现 SimplePromise 和 SimpleFuture 两个类&#xff0c;二者通过一个共享状态实现线程间的通信…...

MATLAB(Octave)混电动力能耗评估

&#x1f3af;要点 处理电动和混动汽车能耗的后向和前向算法模型(simulink)&#xff0c;以及图形函数、后处理函数等实现。构建储能元数据信息&#xff1a;电池标称特性、电池标识符等以及静止、恒定电流和恒定电压等特征阶段。使用电流脉冲或要识别的等效电路模型类型配置阻抗…...

opencv学习:人脸识别器特征提取BPHFaceRecognizer_create算法的使用

BPHFaceRecognizer_create算法 在OpenCV中&#xff0c;cv2.face.LBPHFaceRecognizer_create()函数用于创建一个局部二值模式直方图&#xff08;Local Binary Patterns Histograms&#xff0c;简称LBPH&#xff09;人脸识别器。LBPH是一种用于人脸识别的特征提取方法&#xff0…...

HTML+CSS总结【量大管饱】

文章目录 前言HTML总结语义化标签常用标签H5新的语义元素H5的媒体标签\<embed> 元素&#xff08;少用&#xff09;\<object>元素&#xff08;少用&#xff09;\<audio>\<video> 元素包含关系iframe元素嵌入flash内容常用表单inputselect CSS总结权重样…...

Android开发之Broadcast Receive(广播机制)其实开发如此简单

什么是BroadcastReceiver BroadcastReceiver&#xff08;广播接收器&#xff09;用于响应来自其他应用程序或者系统的广播消息。这些消息有时被称为事件或者意图。本质上来讲BroadcastReceiver是一个全局的监听器&#xff0c;隶属于Android四大组件之一。 使用场景 1、 不同…...

Chromium 中chrome.cookies扩展接口c++实现分析

chrome.cookies 使用 chrome.cookies API 查询和修改 Cookie&#xff0c;并在 Cookie 发生更改时收到通知。 更多参考官网定义&#xff1a;chrome.cookies | API | Chrome for Developers (google.cn) 本文以加载一个清理cookies功能扩展为例 https://github.com/Google…...

excel筛选多个单元格内容

通常情况下&#xff0c;excel单元格筛选时&#xff0c;只筛选一个条件&#xff0c;如果要筛选多个条件&#xff0c;可以如下操作&#xff1a; 字符串中间用空格分隔就行。...

Instant 和 Duration 类(进行时间处理)

Instant Instant 类是 Java 8 中引入的&#xff0c;用于表示一个具体的时间点&#xff0c;它基于 UTC&#xff08;协调世界时&#xff09;时区。以下是 Instant 类的一些常用方法及其简要说明&#xff1a; now()&#xff1a;获取当前的 Instant 对象&#xff0c;表示当前时间…...

Java每日面试题(Spring)(day19)

目录 Spring的优点什么是Spring AOP&#xff1f;AOP有哪些实现方式&#xff1f;JDK动态代理和CGLIB动态代理的区别&#xff1f;Spring AOP相关术语Spring通知有哪些类型&#xff1f;什么是Spring IOC&#xff1f;Spring中Bean的作用域有哪些&#xff1f;Spring中的Bean什么时候…...

【多线程】线程池(上)

文章目录 线程池基本概念线程池的优点线程池的特点 创建线程池自定义线程池线程池的工作原理线程池源码分析内置线程池newFixedThreadPoolSingleThreadExecutornewCachedThreadPoolScheduledThreadPool 线程池的核心线程是否会被回收?拒绝策略ThreadPoolExecutor.AbortPolicyT…...

ansible 语句+jinjia2+roles

文章目录 1、when语句1、判断表达式1、比较运算符2、逻辑运算符3、根据rc的返回值判断task任务是否执行成功5、通过条件判断路径是否存在6、in 2、when和其他关键字1、block关键字2、rescue关键字3、always关键字 3、ansible循环语句1、基于列表循环(whith_items)2、基于字典循…...

【Docker项目实战】使用Docker部署HumHub社交网络平台

【Docker项目实战】使用Docker部署HumHub社交网络平台 一、HumHub介绍1.1 HumHub简介1.2 HumHub特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载HumHub镜…...

“医者仁术”再进化,AI让乳腺癌筛查迎难而上

世卫组织最新数据显示&#xff0c;我国肿瘤疾病仍然呈上升趋势&#xff0c;肿瘤防控形势依然比较严峻。尤其是像乳腺癌等发病率较高的疾病&#xff0c;早诊断和早治疗意义重大&#xff0c;能够有效降低病死率。 另一方面&#xff0c;中国地域广阔且发展不平衡&#xff0c;各地…...

安卓流式布局实现记录

效果图&#xff1a; 1、导入第三方控件 implementation com.google.android:flexbox:1.1.0 2、布局中使用 <com.google.android.flexbox.FlexboxLayoutandroid:id"id/baggageFl"android:layout_width"match_parent"android:layout_height"wrap_co…...

-bash gcc command not found解决方案(CentOS操作系统)

以 CentOS7 为例&#xff0c;执行以下语句 : yum install gcc如果下载不成功&#xff0c;并且网络没有问题。 执行以下语句 : cp -r /etc/yum.repos.d /etc/yum.repos.d.bakrm -f /etc/yum.repos.d/*.repocurl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.…...

(二)Python输入输出函数

一、输入函数 input函数&#xff1a;用户输入的数据&#xff0c;以字符串形式返回&#xff1b;若需数值类型&#xff0c;则进行类型转换。 xinput("请入你喜欢的蔬菜&#xff1a;") print(x) 二、输出函数 print函数 输出单一数值 x666 print(x) 输出混合类型…...

从调用NCCL到深入NCCL源码

本小白目前研究GPU多卡互连的方案&#xff0c;主要参考NCCL和RCCL进行学习&#xff0c;如有错误&#xff0c;请及时指正&#xff01; 内容还在整理中&#xff0c;近期不断更新&#xff01;&#xff01; 背景介绍 在大模型高性能计算时会需要用到多卡&#xff08;GPU&#xf…...

深入理解Transformer的笔记记录(精简版本)NNLM → Word2Vec

文章的整体介绍顺序为&#xff1a; NNLM → Word2Vec → Seq2Seq → Seq2Seq with Attention → Transformer → Elmo → GPT → BERT 自然语言处理相关任务中要将自然语言交给机器学习中的算法来处理&#xff0c;通常需要将语言数学化&#xff0c;因为计算机机器只认数学符号…...

优选算法第一讲:双指针模块

优选算法第一讲&#xff1a;双指针模块 1.移动零2.复写零3.快乐数4.盛最多水的容器5.有效三角形的个数6.查找总价格为目标值的两个商品7.三数之和8.四数之和 1.移动零 链接: 移动零 下面是一个画图&#xff0c;其中&#xff0c;绿色部分标出的是重点&#xff1a; 代码实现&am…...

智能优化算法-水循环优化算法(WCA)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 水循环优化算法 (Water Cycle Algorithm, WCA) 是一种基于自然界水循环过程的元启发式优化算法&#xff0c;由Shah-Hosseini于2012年提出。WCA通过模拟水滴在河流、湖泊和海洋中的流动过程&#xff0c;以及蒸发…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...