c++中如何使用std::async_c++异步执行任务并获取结果【汇总】
发布时间 - 2026-01-22 00:00:00 点击率:次std::async默认策略为std::launch::deferred | std::launch::async,可能延迟或同步执行;必须显式指定std::launch::async才能确保真正异步;future需保存并调用get()/wait(),且get()仅能调用一次,异常在get时抛出,临时future析构会阻塞。
std::async 不是“开个线程就完事”,它默认行为取决于启动策略,不显式指定 std::launch::async 时可能延迟执行甚至同步调用——这是最常被忽略的坑。
std::async 默认启动策略是 std::launch::deferred | std::launch::async
这意味着:系统可自由选择立即异步执行,或推迟到 get() / wait() 时才同步执行。你写的是“异步调用”

- 想确保真正并发执行,必须显式传入
std::launch::async - 若只传函数对象不传策略,
std::async(func)的行为不可移植,GCC、Clang、MSVC 在某些优化级别下都可能走deferred -
std::launch::deferred模式下,get()会立刻同步执行并返回结果,无任何并发;此时wait_for(...)永远返回std::future_status::deferred
std::future::get() 只能调用一次
调用后 future 状态变为“已获取”,再次调用会抛出 std::future_error(错误码为 std::future_errc::no_state 或 std::future_errc::future_already_retrieved)。
- 常见误操作:
auto res = f.get(); auto res2 = f.get();→ 第二行崩溃 - 若需多次访问结果,应把
get()结果存为变量,或改用std::shared_future -
std::shared_future支持多线程多次get(),但需由std::future::share()构造:auto sf = f.share();
异常传播:async 内部抛异常,get() 会 rethrow
std::async 包裹的函数若抛异常,不会终止程序,而是被捕获并存储在 future 对象中;直到调用 get() 才原样抛出。
- 这既是优点(避免线程猝死),也是陷阱(异常被静默吞掉,直到 get 才暴露)
- 若忘记调用
get()或wait(),异常永远不会浮现,还可能导致资源泄漏(如 future 析构时未取结果,C++11 规定会阻塞等待完成,但异常仍被丢弃) - 安全写法:始终在作用域结束前调用
get()或wait(),或用 RAII 封装(例如自定义scoped_future类)
生命周期管理:future 必须存活到任务完成
std::async 返回的 std::future 管理后台任务的生命周期。如果 future 提前析构且任务尚未完成,析构行为取决于启动策略:
-
std::launch::async:future 析构会阻塞,等待任务结束(C++11 起强制要求) -
std::launch::deferred:future 析构不执行任务,任务永远丢失 - 因此,不要让 future 成为临时对象然后丢弃:
std::async(std::launch::async, []{ /*...*/ });是危险的——任务虽启动,但 future 立即销毁,主线程可能在任务完成前就退出
#include#include #include int heavy_work() { std::this_thread::sleep_for(std::chrono::seconds(2)); return 42; } int main() { // ✅ 正确:显式 async 策略 + 保存 future + 主动 get auto fut = std::async(std::launch::async, heavy_work); std::cout << "waiting...\n"; int result = fut.get(); // 阻塞直到完成 std::cout << "result = " << result << "\n"; // ❌ 危险:临时 future,析构时阻塞,但意图不明确 // std::async(std::launch::async, []{ std::this_thread::sleep_for(1s); }); return 0; }
真正麻烦的不是语法,而是 launch 策略的隐式性、future 生命周期与异常传播的耦合——这三个点没对齐,std::async 就会从便利工具变成隐蔽的竞态/阻塞源。
# 工具
# ai
# c++
# ios
# stream
# 作用域
# red
# 封装
# auto
# 线程
# 多线程
# 主线程
# 并发
# 对象
# 异步
# 抛出
# 的是
# 这是
# 就会
# 能在
# 自定义
# 无任何
# 永远不会
# 开个
# 这三个
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Android GridView 滑动条设置一直显示状态(推荐)
Laravel如何优化应用性能?(缓存和优化命令)
如何快速查询网站的真实建站时间?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
微信小程序 wx.uploadFile无法上传解决办法
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
如何在新浪SAE免费搭建个人博客?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Android okhttputils现在进度显示实例代码
如何在阿里云服务器自主搭建网站?
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
制作企业网站建设方案,怎样建设一个公司网站?
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
Bootstrap整体框架之JavaScript插件架构
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
免费网站制作appp,免费制作app哪个平台好?
iOS中将个别页面强制横屏其他页面竖屏
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
打造顶配客厅影院,这份100寸电视推荐名单请查收
高端智能建站公司优选:品牌定制与SEO优化一站式服务
西安专业网站制作公司有哪些,陕西省建行官方网站?
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
Laravel怎么清理缓存_Laravel optimize clear命令详解
Laravel如何使用Blade组件和插槽?(Component代码示例)
如何快速搭建高效WAP手机网站?
如何在云指建站中生成FTP站点?
微信公众帐号开发教程之图文消息全攻略
详解vue.js组件化开发实践
Mybatis 中的insertOrUpdate操作
常州企业网站制作公司,全国继续教育网怎么登录?
微信小程序 scroll-view组件实现列表页实例代码
如何快速启动建站代理加盟业务?
如何在云虚拟主机上快速搭建个人网站?
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
Linux安全能力提升路径_长期防护思维说明【指导】
Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置
百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏

