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_statestd::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聊天窗口隐藏