C++如何使用std::async进行异步编程?(future用法)
技术百科
尼克
发布时间:2026-01-01
浏览: 次 必须通过std::future的get()或wait()获取结果或等待完成,否则可能阻塞析构;支持async、deferred及二者组合策略,future为单次使用,异常被捕获并重抛,shared_future允许多次读取。
用 std::async 启动异步任务后,必须通过 std::future 获取结果或等待完成;不调用 get() 或 wait() 可能导致线程资源未释放、程序阻塞在析构时。
std::async 的三种启动策略
std::async 支持三种 std::launch 策略,决定任务何时执行:
- std::launch::async:强制新线程立即执行(真正异步)
-
std::launch::deferred:延迟执行,直到调用
future.get()或future.wait()时才在当前线程运行(类似惰性求值) - std::launch::async | std::launch::deferred(默认):由标准库决定——通常优先异步,但可能退化为延迟执行(尤其系统负载高时)
显式指定策略更可控。例如:auto f = std::async(std::launch::async, []{ return 42; });
future 的核心操作:get() 与 wait()
std::future 是单次使用的同步原语,关键行为如下:
-
get():阻塞等待结果,返回值(或抛出异常),且只能调用一次;第二次调用会抛出std::future_error -
wait():仅阻塞等待完成,不取值,可多次调用(但无实际意义) -
wait_for()和wait_u:带超时的等待,返回
ntil()std::future_status(ready/timeout/deferred)
注意:即使任务已结束,get() 仍会移动内部存储的值或异常,之后 future 处于无效状态。
处理异常和共享状态
异步函数内抛出的异常不会崩溃程序,而是被捕获并存入 future 中:
- 调用
get()时,若任务抛过异常,该异常会被重新抛出(类型不变) - 多个
future可通过std::shared_future共享同一结果(适用于多处读取场景) -
std::shared_future支持多次get(),需由future.share()转换获得
示例:auto sf = f.share(); auto a = sf.get(); auto b = sf.get(); // 合法
生命周期管理要点
std::future 析构时,若关联的异步任务仍在运行且策略为 async,析构会阻塞直到任务完成——这是常见陷阱:
- 避免临时
future:如std::async(...).get();会立刻阻塞,失去异步意义 - 确保
future对象存活到你准备取结果时;推荐用命名变量持有 - 若需“只管启动、不关心结果”,可用
std::async(std::launch::async, ...);(但注意析构仍会等)
真正“fire-and-forget”应配合 std::thread + 分离,或封装成不返回 future 的接口。
# ai
# 这是
# 到你
# 多个
# 可通过
# 适用于
# 三种
# 时才
# auto
# 对象
# c++
# 标准库
# 接口
# 线程
# 异步
# red
# 封装
# Thread
# 抛出
# 异步任务
# 仍会
# 多处
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Python网页解析流程_html结构说明【指导】
- php订单日志权限怎么设_php订单日志文件权限设
- Win11如何关闭小娜Cortana Win11禁
- Windows10怎么用“讲述人”读屏辅助 Win
- c++中如何使用auto关键字_c++11类型推导
- Win11怎么用设置清理回收站_Win11设置清理
- Win11如何设置鼠标灵敏度_Win11鼠标灵敏度
- 获取 PHP 文件最后修改时间的正确方法
- php8.4新语法match怎么用_php8.4m
- Win10系统怎么查看端口状态_Windows10
- php怎么下载安装后测试是否成功_简单脚本验证方法
- php8.4xdebug无法调试怎么办_php8.
- MAC如何设置网卡MAC地址克隆_MAC终端修改物
- 如何在 Windows 11 中使用 AlomWa
- Python文本编码与解码_跨平台解析说明【指导】
- Win11怎么更改盘符_Win11磁盘管理修改驱动
- Win11怎么关闭开机声音_Win11系统启动提示
- Win11怎么设置默认PDF阅读器 Win11修改
- win11如何清理传递优化文件 Win11为C盘瘦
- 如何在Mac上搭建Golang开发环境_使用Hom
- php怎么连接数据库_MySQL数据库连接的基础代
- Win11文件夹预览图不显示怎么办_Win11缩略
- 使用类变量定义字符串常量时的类型安全最佳实践
- 如何提升Golang JSON序列化性能_Gola
- 为什么Go建议使用error接口作为错误返回_Go
- Python项目回滚策略_发布安全说明【指导】
- 如何使用Golang构建简易投票统计功能_Gola
- Python对象生命周期管理_创建销毁解析【教程】
- Win11怎么关闭系统透明度_Windows11个
- Win11怎么设置开机自动连接宽带_Windows
- Bpmn 2.0的XML文件怎么画流程图
- 如何使用正则表达式精确匹配最多含一个换行符的 st
- Win11怎么关闭系统推荐内容_Windows11
- c++中explicit(bool)的用法 c++
- mac怎么安装字体_MAC添加第三方字体与字体册管
- PHP主流架构怎么处理表单验证_规则与自定义【技巧
- 如何使用Golang sync.Map实现并发安全
- 如何使用Golang reflect检查方法数量_
- 如何在 Go 中比较自定义的数组类型(如 [20]
- Win11怎么设置任务栏大小_Windows11注
- Windows11如何设置专注助手_Windows
- 如何在 Django 中安全修改用户密码而不使会话
- Win11如何暂停系统更新 Win11暂停更新最长
- 如何使用Golang模拟请求超时_Golang c
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- Python网络日志追踪_请求定位解析【教程】
- 如何使用Golang实现文件加密_Golang c
- php嵌入式需要什么环境_搭建php+linux嵌
- ACF 教程:正确更新嵌套在多层 Group 字段
- 如何在 ACF 中正确更新嵌套多层的 Group

ntil()
QQ客服