c++ std::future和std::promise c++线程间通信【教程】


std::future 和 std::promise 是 C++11 提供的线程安全异步值传递机制,用于单次结果传递;promise 设置值或异常(仅一次),future 通过 get() 获取(仅一次),二者通过共享状态关联,支持移动但不可拷贝。

std::future 和 std::promise 是 C++11 引入的一对配套工具,用于在线程间安全地传递单次结果值,适合“一个线程生产、另一个线程消费”的场景。它们不共享内存,也不需要手动加锁,本质是基于同步通道的异步值传递机制。

std::promise 负责设置结果值

每个 std::promise 对象关联一个共享状态(shared state),它只能被调用一次 set_value()set_exception()set_exception_at_thread_exit()。多次调用会抛出 std::future_error 异常。

  • promise 必须在设置值前,把对应的 future 交给消费者线程(通常通过 move 语义转移)
  • promise 对象本身可被移动,但不可拷贝;它的 shared state 是线程安全的
  • 如果 promise 被销毁而未设置值,其 shared state 会以 std::future_error 异常结束

std::future 负责获取结果值

future 是 promise 的“读取端”,通过 get() 阻塞等待并取出值(或异常)。get() 只能调用一次,之后 future 失效(变为无效状态)。

  • 调用 get() 会阻塞当前线程,直到 promise 设置了值或异常
  • future 支持 wait()、wait_for()、wait_until() 等非阻塞等待方式,用于轮询或超时控制
  • future 也可由 std::async、std::packaged_task 自动创建,不一定非要配对使用 promise

典型协作流程示例

以下是一个跨线程传递 int 值的最小可行代码:

#include 
#include 
#include 

int main() {
    std::promise p;
    std::future f = p.get_future(); // 获取关联 future

    std::thread t([&p]() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        p.set_value(42); // 生产者设值
    });

    std::cout << "等待中..." << std::endl;
    int result = f.get(); // 消费者取值(阻塞)
    std::cout << "得到:" << result << std::endl;

    t.join();
}

注意:lambda 捕获 promise 时需用引用(&p),否则 set_value 作用于副本,主线程将永远阻塞。

常见陷阱与建议

  • 避免复制 future 或 promise —— 它们都只支持移动语义
  • 不要在 promise 析构前忘记 set_value;可用 std::optional + RAII 封装规避
  • 若需多次通信,不要强行复用 future/promise;改用 std::queue + mutex 或 std::condition_variable
  • 异常传播很自然:promise.set_exception(std::make_exception_ptr(...)),future.get() 会重新抛出


# 工具  # ai  # c++  # ios  # stream  # red  # 封装  # int  # Lambda  # 线程  # 主线程  # 值传递  # 对象  # promise  # 异步  # 抛出  # 是一个  # 也不  # 非要  # 会以  # 都只  # 可由  # 时需  # 作用于  # 加锁 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Win10任务栏天气和资讯怎么关闭 Win10禁用新闻和兴趣功能【教程】  c# 在高并发下使用反射发射(Reflection.Emit)的性能  Django 测试数据库表缺失与字段未创建问题的完整解决方案  Win11怎么设置虚拟内存_Windows 11优化内存性能提升速度【技巧】  c++怎么使用std::tuple存储多元组数据_c++ 11获取元素与解包操作【技巧】  php删除数据怎么软删除_添加is_del字段标记删除【技巧】  Python项目维护经验_长期演进说明【指导】  如何使用Golang实现容器自动化运维_Golang Docker运维管理方法  Python多线程使用规范_线程安全解析【教程】  php中::能用于接口静态方法吗_接口静态方法调用规则【操作】  如何使用Golang sort排序切片_Golang sort排序方法示例  php本地部署后数据库连接报错_1045accessdenied错误解决方法详解【汇总】  VSC怎样用终端运行PHP_命令行执行脚本的步骤【教程】  Win10电脑怎么设置网络名称_Windows10注册表NetworkList修改  MAC怎么在照片中添加水印_MAC自带编辑工具文字水印叠加【方法】  Windows10系统怎么查看设备管理器_Win10快捷键Win+X菜单使用  Win11怎么卸载Photos应用_Win11卸载Photos应用方法【教程】  Win10怎样清理C盘阿里旺旺缓存_Win10清理阿里旺旺缓存步骤【步骤】  Win11怎么设置任务栏对齐方式_Windows11个性化任务栏行为  Win11怎么关闭系统透明度_Windows11个性化颜色透明效果  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  Win11怎么设置任务栏大小_Windows11注册表修改TaskbarSi值  Linux如何安装Golang环境_Linux下Go语言开发包配置【方法】  如何在Golang中处理二进制数据_Golang io与encoding/binary二进制操作方法  Mac如何彻底清理浏览器缓存?(Safari与Chrome)  Windows 10自带杀毒软件在哪_Windows 10打开和使用Windows安全中心  如何在同包不同文件中正确引用 Go 结构体  Win11开机Logo怎么换_Win11自定义启动画面工具【高级】  c++怎么用jemalloc c++替换默认内存分配器【性能】  php怎么下载安装后测试是否成功_简单脚本验证方法【操作】  php嵌入式需要什么环境_搭建php+linux嵌入式开发环境【详解】  Python安全爬虫设计_IP代理池与验证码识别策略解析  Windows10如何重置此电脑_Windows10电脑重置方法【步骤】  Windows10如何更改桌面背景_Win10个性化幻灯片放映设置  Windows如何使用注册表查找和删除项?(regedit教程)  c++怎么使用std::filesystem遍历文件夹_c++ 递归查找文件与权限修改【技巧】  如何在 Django 中安全修改用户密码而不使会话失效  Win11怎么退出微软账户_切换Win11为本地账户登录方法【详解】  Drupal 中 HTML 链接被重复转义导致渲染异常的解决方案  Windows服务启动类型恢复方法_错误修改导致的系统服务异常  Win11如何隐藏桌面图标 Win11一键隐藏/显示桌面图标【指南】  MAC如何安装Git版本控制工具_MAC开发环境配置与Xcode插件安装【教程】  Win11怎么关闭透明效果_Windows11个性化颜色关闭透明  PHP接收参数值为空怎么办_判断和处理空参数方法说明【说明】  Python函数接口稳定性_版本演进解析【指导】  php本地部署支持nodejs吗_php与nodejs混合开发环境搭建教程【教程】  Python装饰器设计思路_功能增强机制说明【指导】  Win11怎么更改计算机名_Windows11系统信息重命名设备教程  Win11怎么把图标拖到任务栏_Win11固定应用快捷方式指南【方法】  PHP主流架构如何处理会话管理_Session与Cookie【技巧】 

 2026-01-02

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.