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; ?>
】
相关推荐
- MAC怎么用连续互通相机里的“桌上视角”_MAC在
- 如何在 Python 中将 ISO 8601 时间
- Win11怎么关闭系统声音_Win11系统提示音静
- Win11怎么退出微软账户_切换Win11为本地账
- 如何在 ACF 中正确更新嵌套多层的 Group
- 如何在 Go 中比较自定义的数组类型(如 [20]
- php本地部署后session无法保存_sessi
- Windows11怎么自定义任务栏_Windows
- MAC怎么解压RAR格式文件_MAC第三方解压工具
- 如何在Golang中使用encoding/gob序
- Python集合操作技巧_高效去重解析【教程】
- 如何使用Golang recover捕获panic
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- Win11如何设置ipv6 Win11开启IPv6
- 如何使用Golang实现容器健康检查_监控和自动重
- Win10如何关闭安全中心所有通知 Win10禁用
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Windows如何设置登录时的欢迎屏幕背景?(锁屏
- 如何高效获取循环末次生成的 NumPy 数组最后一
- php订单日志怎么按金额排序_php按订单金额排序
- 如何在 Pandas 中按元素交集合并两列字符串
- Win11怎么设置虚拟桌面 Win11新建多桌面切
- SAX解析器是什么,它与DOM在处理大型XML文件
- Win11怎么退出高对比度模式_Win11取消反色
- php修改数据怎么批量改状态_批量更新status
- Win11怎么设置默认输入法 Win11固定中文输
- Python性能剖析高级教程_cProfileLi
- Win11如何设置省电模式 Win11开启电池节电
- Windows蓝屏错误0x0000002C怎么解决
- Windows10电脑怎么设置自动连接WiFi_W
- 如何在 IIS 上为 ASP.NET 6 应用排除
- Win11怎么用设置清理回收站_Win11设置清理
- c++怎么使用类型萃取type_traits_c+
- Win11屏幕亮度突然变暗怎么解决_自动变暗问题处
- Mac版Final Cut Pro入门_Mac视频
- Win11怎么关闭通知消息_屏蔽Windows 1
- 如何用正则表达式精确匹配“start”到“end”
- 如何优化Golang内存分配与GC调度_Golan
- 如何使用Golang编写单元测试_创建Test函数
- Python与OpenAI接口集成实战_生成式AI
- Windows怎样拦截WPS弹窗广告_Window
- Windows10电脑怎么设置文件权限_Win10
- LINUX怎么进行文本内容搜索_Linux gre
- PHP主流架构怎么部署到Docker_容器化流程【
- php怎么下载安装并配置环境变量_命令行调用PHP
- Win10如何更改电脑休眠时间_Windows10
- php删除数据怎么加限制_带where条件删除避免
- 如何使用Golang reflect检查方法数量_
- c# F# 的 MailboxProcessor
- 如何在Golang中写入JSON文件_保存结构体数

ntil()
QQ客服