c++中如何使用std::async实现简单的并发任务_c++异步编程【实例】

发布时间 - 2026-01-31 00:00:00    点击率:
必须显式指定 std::launch::async 才真正并发;未取值的 future 析构会触发 std::terminate;捕获局部变量需确保生命周期安全,推荐值捕获或 shared_ptr。

直接用 std::async 启动一个异步任务,最简方式就是调用它并获取 std::future,但默认启动策略(std::launch::deferredstd::launch::async)不明确,容易误以为“已并发执行”,结果

变成延迟调用——这是新手踩坑最多的地方。

必须显式指定 std::launch::async 才真正并发

如果不传启动策略,std::async 可能选择 deferred:函数体直到调用 get()wait() 时才执行,且在调用线程中同步运行,根本没开新线程。

  • 永远显式写 std::async(std::launch::async, ...) 来确保立即派生线程
  • std::launch::deferred | std::launch::async 是合法组合,但行为由实现决定,不可靠
  • C++20 起,std::launch::async 是唯一能保证异步执行的策略

获取返回值前必须处理异常或调用 get()

std::future 析构时若未取值,且异步任务抛出异常,则程序会调用 std::terminate——不是崩溃,是直接终止,无堆栈、无提示。

  • 务必在 future 生命周期内调用 get()(哪怕只读一次)
  • 若不关心返回值,可用 wait() 等待完成,但依然要确保异常被传播出来(get() 会重新抛出)
  • 推荐用 try-catch 包裹 get(),尤其当异步函数可能失败时

多个 std::async 任务需注意资源竞争与生命周期

每个 std::async 默认使用系统线程池(具体实现依赖标准库),但线程数不受控;同时捕获局部变量时,若异步任务生命周期超过变量作用域,就会悬垂引用。

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

  • 避免按值捕获大对象,优先用 std::move 或共享指针(如 std::shared_ptr
  • 不要在 lambda 中直接捕获局部栈变量的引用([&]),除非能 100% 确保其存活到任务结束
  • 大量任务建议改用线程池(如 boost::asio::thread_pool 或自建),std::async 不适合高吞吐调度
int main() {
    // 正确:显式 async,捕获值,安全等待
    auto fut1 = std::async(std::launch::async, []{ return 42; });
    auto fut2 = std::async(std::launch::async, []{ 
        std::this_thread::sleep_for(100ms); 
        return 100; 
    });

    // 必须 get(),否则析构时异常导致 terminate
    try {
        int a = fut1.get();  // 阻塞直到完成
        int b = fut2.get();
        std::cout << a + b << "\n";  // 输出 142
    } catch (const std::exception& e) {
        std::cerr << "Async task failed: " << e.what() << "\n";
    }
}

真正麻烦的从来不是怎么写那几行 std::async,而是谁来管理线程生命周期、异常怎么透出、结果怎么聚合、任务失败后要不要重试——这些 std::async 一概不管,得你自己兜底。


#   # ai  # c++  # 异步任务  # 作用域  # 标准库  # red  # try  # catch  # 局部变量  # int  # 变量作用域  # Lambda  # 指针  #   # 线程  # 线程生命周期  # 并发  # 对象  # 异步  # 抛出  # 返回值  # 这是  # 就会  # 多个  # 最多  # 是怎么  # 你自己  # 不适合  # 谁来 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: bing浏览器学术搜索入口_bing学术文献检索地址  Laravel如何使用Eloquent进行子查询  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Python正则表达式进阶教程_复杂匹配与分组替换解析  千库网官网入口推荐 千库网设计创意平台入口  打造顶配客厅影院,这份100寸电视推荐名单请查收  如何用wdcp快速搭建高效网站?  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  Laravel如何创建自定义Artisan命令?(代码示例)  深圳网站制作培训,深圳哪些招聘网站比较好?  Python自动化办公教程_ExcelWordPDF批量处理案例  在线制作视频网站免费,都有哪些好的动漫网站?  iOS正则表达式验证手机号、邮箱、身份证号等  如何快速使用云服务器搭建个人网站?  EditPlus 正则表达式 实战(3)  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  企业网站制作这些问题要关注  Laravel如何实现模型的全局作用域?(Global Scope示例)  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  如何在IIS中新建站点并配置端口与物理路径?  原生JS实现图片轮播切换效果  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  如何解决hover在ie6中的兼容性问题  如何用虚拟主机快速搭建网站?详细步骤解析  Laravel如何与Pusher实现实时通信?(WebSocket示例)  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  如何快速搭建高效简练网站?  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  html5的keygen标签为什么废弃_替代方案说明【解答】  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  Laravel怎么在Controller之外的地方验证数据  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  创业网站制作流程,创业网站可靠吗?  android nfc常用标签读取总结  Laravel如何实现用户密码重置功能?(完整流程代码)  b2c电商网站制作流程,b2c水平综合的电商平台?  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置  太平洋网站制作公司,网络用语太平洋是什么意思?  JavaScript如何实现继承_有哪些常用方法  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  如何快速生成专业多端适配建站电话?  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  Laravel如何使用Blade模板引擎?(完整语法和示例)