0

0

C++的std::promise和std::future如何实现线程间的一对一同步? (状态共享机制)

穿越時空

穿越時空

发布时间:2026-02-16 16:32:03

|

972人浏览过

|

来源于php中文网

原创

std::promise与std::future需通过get_future()显式配对,一 promise 仅可绑定一 future;set_value()触发wait()/get()返回,get()只可调用一次,promise析构前未设置值则get()抛broken_promise。

c++的std::promise和std::future如何实现线程间的一对一同步? (状态共享机制)

std::promise 和 std::future 怎么配对传递值?

它们不是自动绑定的,必须通过 std::promise::get_future() 显式获取对应 std::future,且只能调用一次。一旦获取,std::promisestd::future 就共享底层状态对象(通常叫 __state 或类似实现细节),后续对 std::promise::set_value() 的调用会触发 std::future::wait()std::future::get() 返回。

常见错误现象:std::future 构造后未从同一 std::promise 获取,或重复调用 get_future() —— 后者会抛出 std::future_error(错误码为 std::future_errc::future_already_retrieved)。

  • 一个 std::promise 只能关联一个 std::future;反之不成立(但多对一无意义,也不支持)
  • 不能把 std::promise 拷贝给另一个线程,它不可拷贝;必须移动(std::move(p))或用指针/智能指针传递
  • std::future 本身可移动,但移动后原对象变为无效状态(valid() == false

为什么 set_value() 后 get() 不卡死,但 wait() 还要等?

因为 std::promise::set_value() 是“发信号”动作,它设置共享状态为 ready,并唤醒所有等待该状态的线程;而 std::future::get() 在返回前会隐式调用 wait(),再读取值 —— 所以它既同步又取值。但 wait() 只同步、不取值,适合只关心完成时机、不关心结果内容的场景(比如纯屏障)。

性能影响:如果值类型大且不需要立即使用,先 wait()get() 可避免不必要的拷贝延迟(不过现代编译器常优化掉);若值小或必须立刻消费,直接 get() 更简洁。

立即学习C++免费学习笔记(深入)”;

Grammarly
Grammarly

Grammarly是一款在线语法纠正和校对工具,伟大的AI辅助写作工具

下载
  • get() 只能调用一次,第二次会抛 std::future_errorstd::future_errc::no_state
  • 若 promise 被析构前未调用 set_value()set_exception()set_value_at_thread_exit(),则 future::get() 会抛 std::future_errorstd::future_errc::broken_promise
  • 不要在 promise 所在线程里直接调用 future::get() —— 它会永远阻塞,除非 promise 在另一线程中设置

std::promise 能用来做纯信号同步吗?

可以,而且很常用。当只需要通知“某事已完成”,不传数据时,std::promise<void></void> 配合 std::future<void></void> 是轻量级选择。它的 set_value() 不带参数,get() 返回 void,语义清晰。

容易踩的坑:有人误以为 std::future<void>.wait()</void> 等价于 std::condition_variable + std::mutex,其实不然——std::future<void></void> 不支持超时等待(wait_for/wait_until 是有的,但 void 版本仍受限于底层实现是否真正支持),且无法重置、无法多次通知。

  • 适合一次性同步点(如初始化完成、任务结束)
  • 不适用于需要多次触发、或需响应中断/超时的场景
  • 若需超时,必须用 std::future<t>::wait_for()</t>,但 void 类型下返回值仍是 std::future_status,不能忽略

跨线程传递 promise/future 时要注意什么?

核心是生命周期管理:promise 必须活到被 set_value() 调用之后,future 必须活到 get()/wait() 返回之后。最安全的方式是用 std::shared_ptr<:promise>></:promise> 包裹 promise,在生产者和消费者之间共享所有权;future 通常由消费者独占持有,无需共享。

典型错误:把局部 std::promise 对象 move 进线程函数,但主线程函数返回后 promise 被析构,子线程再调用 set_value() 就是未定义行为。

  • 推荐模式:在创建线程前 new 一个 std::promise,用 std::shared_ptr 管理;或直接用 std::packaged_task 替代手动配对
  • 避免裸指针传递 promise/future,尤其不要让多个线程同时写同一个 promise(set_value() 非线程安全,仅保证对同一 promise 的多次 set 是互斥的)
  • future 的 wait()get() 是线程安全的,可被多个线程并发调用(但结果未定义:只有一个能成功取值,其余抛异常)

真正麻烦的从来不是怎么调用那几个函数,而是谁在什么时候销毁 promise、谁还在等着 future、以及有没有人忘了 set_value —— 这些问题不会报编译错误,但会让程序在某个负载下突然 hang 住或崩溃。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

114

2025.11.27

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

675

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

675

2023.08.10

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

320

2023.10.12

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

416

2023.10.12

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

148

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

102

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

35

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.6万人学习

C 教程
C 教程

共75课时 | 4.8万人学习

C++教程
C++教程

共115课时 | 18万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号