讲师中心 微信公众号
AI工具推荐 视频效率加速

C++ future与promise异步编程 _ 获取子线程返回值方法【详解】

浅伟大大_5016

浅伟大大_5016

发布时间:2026-04-14 17:27:34

|

1004人浏览过

|

来源于php中文网

原创

std::future::get() 一调用就崩溃,主因是空 future(如 std::future f;)调用 get() 会抛出 std::future_error(no_state) 异常;若未捕获则触发 std::terminate() 导致程序崩溃。卡死通常源于 std::async 默认延迟执行策略(deferred),get() 时才同步运行函数,而非真异步。

c++ future与promise异步编程 _ 获取子线程返回值方法【详解】

std::future::get() 为什么一调用就崩溃或卡死

直接声明 std::future<int></int> 而不绑定任何 std::promise,是常见崩溃源头。这种空 future 没有共享状态,调用 get() 或 wait() 会抛 std::future_error(错误码为 no_state),不是卡死——是明确异常。

正确路径只有一条:先构造 std::promise<t></t>,再通过其 get_future() 获取合法 future。别试图“后期绑定”或复用未初始化的 future。

  • std::future<int> f;</int> → 无效对象,后续任何阻塞操作都非法
  • std::promise<int> p; auto f = p.get_future();</int> → 合法起点
  • 若子线程未执行 p.set_value() 或 p.set_exception() 就退出,p 析构时会调用 std::terminate(),不是静默失败

std::promise 只能 set 一次,但怎么传给子线程

std::promise 是 move-only 类型,不能按值拷贝,也不能用 std::ref 直接传引用给 std::thread 构造函数——因为 std::thread 内部会尝试拷贝参数,而 std::promise 拷贝构造被禁用。

安全传参方式只有两种:

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

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 用 std::move() 移动传入(推荐):std::thread t(func, std::move(p));,函数签名需接收右值引用:void func(std::promise<int>&& p)</int>
  • 用指针或智能指针包装后传(如 std::shared_ptr<:promise>></:promise>),但需自行管理生命周期,易引入悬挂指针
  • 绝对避免:std::thread t(func, std::ref(p)); —— 编译失败,std::ref 无法绕过 move-only 限制

std::async 比手动 promise/future 更省事?但有个默认陷阱

std::async 确实省去配对、传参、移动等步骤,但它默认启动策略是 std::launch::async | std::launch::deferred,编译器可自由选择同步还是异步执行。MSVC 默认倾向 deferred(延迟执行),意味着 get() 调用时才真正运行函数——这看起来像同步,破坏了“异步”预期。

要确保真异步,必须显式指定策略:

  • std::async(std::launch::async, func) → 强制新线程
  • std::async(std::launch::deferred, func) → 明确延迟,get() 时才执行
  • 不写策略参数 → 行为不可移植,GCC/Clang 多数 async,MSVC 多数 deferred
  • std::async 返回的 future 在 get() 后也变为无效(valid() == false),多次 get() 同样 UB

move-only 类型(如 std::unique_ptr)怎么从 future 安全取值

std::future<:unique_ptr>></:unique_ptr> 的 get() 返回的是右值引用,结果会被移动走。这意味着:

  • 接收变量必须声明为 auto&& 或 std::unique_ptr<int></int>(隐式移动);写成 std::unique_ptr<int> p = fut.get();</int> 是 OK 的
  • 不能写成 const std::unique_ptr<int>& p = fut.get();</int> —— 绑定临时量到 const 引用延长生命周期,但 get() 移动后原 future 已失效,且该引用可能悬空
  • 如果子线程中用 promise.set_value(std::move(ptr)),主线程 get() 才能成功拿到所有权;漏掉 std::move 会导致编译失败(类型不匹配)
  • 一旦 get() 调用,future 不再可用,再次调用 get() 或 wait() 抛异常

最常被忽略的点:promise 析构前没 set 值,程序直接 terminate,不会报错也不会返回错误码——它不给你补救机会。所有使用 promise 的路径,必须保证无论正常结束还是异常退出,都至少调用一次 set_value 或 set_exception。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2398

2023.09.20

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

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

636

2023.11.23

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

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

371

2025.11.27

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

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

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

4718

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

583

2025.12.01

promise的用法
promise的用法

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

4820

2023.10.12

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

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

4623

2023.10.12

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn