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

浅伟大大_5016

浅伟大大_5016

2026-04-14

1004人浏览

原创

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

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

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

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

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

安全传参方式只有两种:

  • 用 std::move() 移动传入(推荐):std::thread t(func, std::move(p));,函数签名需接收右值引用:void func(std::promise&& p)
  • 用指针或智能指针包装后传(如 std::shared_ptr<: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() 调用时才真正运行函数——这看起来像同步,破坏了“异步”预期。

C++14
C++14

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

下载

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

  • 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>> 的 get() 返回的是右值引用,结果会被移动走。这意味着:

  • 接收变量必须声明为 auto&& 或 std::unique_ptr(隐式移动);写成 std::unique_ptr p = fut.get(); 是 OK 的
  • 不能写成 const std::unique_ptr& p = fut.get(); —— 绑定临时量到 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++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

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

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

下载

相关标签:

c++

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

相关专题

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

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

2023.09.20

2418

7

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

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

2023.11.23

636

5

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

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

2025.11.27

371

13

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

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

2026.04.23

379

31

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

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

2023.08.10

4718

6

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

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

2025.12.01

583

16

promise的用法
promise的用法

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

2023.10.12

4820

6

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

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

2023.10.12

4623

6

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习