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; ?>
】
相关推荐
- 如何使用Golang实现基本类型比较_Golang
- Python性能剖析高级教程_cProfileLi
- PHP 中 require() 语句返回值的用法详
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何使用Golang配置安全开发环境_防止敏感信息
- 如何在Golang中处理二进制数据_Golang
- Win11屏幕亮度突然变暗怎么解决_自动变暗问题处
- Win10电脑C盘红了怎么清理_Windows10
- PHP 中如何在函数内持久化修改引用变量的指向
- Python解释执行模型_字节码流程说明【指导】
- 如何在 Go 中正确反序列化 XML 多节点数组(
- ACF 教程:正确更新嵌套在多层 Group 字段
- Python脚本参数接收_sys与argparse
- 如何在Windows上设置闹钟和计时器_系统自带的
- C++友元类使用场景_C++类间协作设计方式讲解
- Mac怎么进行语音输入_Mac听写功能设置与使用【
- c++中如何对数组进行排序_c++数组排序算法汇总
- c++中的可变参数模板(variadic temp
- c++中如何求一个数的平方根_c++ sqrt函数
- PythonDocker高级项目部署教程_多容器管
- 如何在Golang中处理JSON字段缺失_Gola
- 如何在 Laravel 中通过嵌套关联关系进行 o
- php修改数据怎么改富文本_update更新htm
- Win10怎样卸载iTunes_Win10卸载iT
- Python项目回滚策略_发布安全说明【指导】
- MAC如何设置网卡MAC地址克隆_MAC终端修改物
- MAC怎么使用表情符号面板_MAC Emoji快捷
- Win11怎么关闭粘滞键_彻底禁用Windows
- 如何在Golang中处理模块包路径变化_Golan
- Win11怎么关闭定位服务_保护Win11位置隐私
- Win10怎么更改用户名 Win10修改账户名称操
- 如何在同包不同文件中正确引用 Go 结构体
- Django 密码修改后会话失效的解决方案
- 如何在Golang中使用log包输出不同级别日志_
- 如何使用Golang实现微服务事件驱动_使用消息总
- 如何使用Golang指针与结构体结合_修改结构体内
- Flask 表单数据通过 SMTP 发送邮件的完整
- php订单日志怎么导出excel_php导出订单日
- Win11 C盘满了怎么清理 Win11磁盘清理和
- Python数据挖掘核心算法实践_聚类分类与特征工
- c# 在高并发下使用反射发射(Reflection
- 如何使用Golang实现文件加密_Golang c
- Win11怎样安装搜狗输入法_Win11安装搜狗输
- Win11如何设置ipv6 Win11开启IPv6
- Win10怎样卸载TeamViewer_Win10
- 如何使用Golang开发简单的聊天室消息存储_Go
- c++输入输出流 c++ cin与cout格式化输
- Win11文件夹预览图不显示怎么办_Win11缩略
- Python与Docker容器化部署实战_镜像构建
- PHP cURL GET请求:正确设置请求头与身份

ntil()
QQ客服