0

0

C++中std::async返回值怎么获取_C++异步编程future用法详解【指南】

穿越時空

穿越時空

发布时间:2026-02-05 14:20:43

|

726人浏览过

|

来源于php中文网

原创

std::future 必须显式调用 get() 或 wait() 获取结果,否则析构时可能阻塞;get() 唯一取值且同步,调用后不可再调,异常会通过 get() 重抛,悬垂引用导致未定义行为。

c++中std::async返回值怎么获取_c++异步编程future用法详解【指南】

std::async 返回的 std::future 必须显式获取结果,否则线程可能被阻塞在析构时(尤其用 std::launch::deferred 时);不调用 get()wait() 就丢弃 future,是常见资源卡死源头。

std::future::get() 是唯一能取值且带同步语义的操作

调用 get() 会:① 阻塞直到异步任务完成;② 移动返回值(对右值引用类型);③ 释放内部共享状态。一旦调用过 get(),再次调用会抛出 std::future_error(错误码为 std::future_errc::no_state)。

常见误用:

  • 重复调用 get() —— 程序崩溃
  • 只调用 wait() 不调用 get() —— 值丢了,还可能泄漏线程资源
  • 把 future 存在局部作用域却没取值 —— 析构时若任务未完成,std::launch::async 模式下会阻塞等待;std::launch::deferred 下则直接在析构线程里同步执行(可能引发死锁)

std::async 启动策略影响 get() 行为和线程生命周期

std::async 默认使用 std::launch::async | std::launch::deferred 组合策略,但实际行为依赖实现。显式指定更可控:

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

  • std::launch::async:一定新开线程,get() 阻塞直到该线程完成
  • std::launch::deferred:不启动新线程,任务延迟到首次调用 get()wait() 时,在当前线程同步执行

示例:

auto f1 = std::async(std::launch::deferred, []{ return 42; });
// 此时什么都没发生
f1.get(); // ← 这里才真正执行 lambda,并返回 42

注意:std::launch::deferred 下,wait() 不阻塞也不执行,只有 get()wait_for()/wait_until() 的超时返回后紧接着调用 get() 才触发执行。

拍我AI
拍我AI

AI视频生成平台PixVerse的国内版本

下载

多个 future 怎么安全、高效地等结果?别裸写循环 wait

手动轮询 wait_for(std::chrono::milliseconds(1)) 效率低且易出错。优先用:

  • std::future_status status = fut.wait_for(timeout):非阻塞检查,返回 ready/timeout/deferred
  • std::when_all(C++20)或第三方库如 folly::collectAll:批量等待多个 future
  • 对一组 future,用 std::vector<:future>> + 范围 for + get(),但注意顺序阻塞 —— 第二个 get() 要等第一个完成后再发起等待(不是并发等)

如果真要并发等任意一个就绪,C++11/14 没原生支持,得靠条件变量 + 包装器模拟;C++20 起可用 std::when_any

异常也会通过 future 传播,不 catch 就 terminate

异步任务中抛出的异常,不会导致程序崩溃,而是被捕获并存入 future 对象。但调用 get() 时会重新抛出:

auto f = std::async([]{ throw std::runtime_error("boom"); });
try {
    f.get(); // ← 这里 rethrow
} catch (const std::exception& e) {
    // 处理异常
}

关键点:

  • 即使你忘了 try/catch,只要 get() 被调用,异常就一定会抛出(不是静默吞掉)
  • 如果 get() 永远不调,异常对象一直驻留,但不会影响其他线程
  • 同一 future 只能 get() 一次,异常也只 rethrow 一次

最常被忽略的是:lambda 捕获了局部对象的引用,异步执行时该对象已销毁 —— 这类悬垂引用问题不会在 get() 时报 future 相关错误,而是直接 undefined behavior,调试难度高。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

191

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

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

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

589

2023.08.10

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

5477

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

3121

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

838

2025.12.25

微信网页版文件传输助手教程合集
微信网页版文件传输助手教程合集

本专题整合了微信网页版文件传输助手教程、入口等等内容,阅读专题下面的文章了解更多详细内容。

15

2026.02.04

微信文件过期恢复教程
微信文件过期恢复教程

本专题整合了微信文件过期恢复方法、技巧教程,阅读专题下面的文章了解更多详细内容。

10

2026.02.04

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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