`std::future`--异步的优势
std::future 相比于直接使用线程在 C++ 中有几个重要的优势,主要体现在同步结果获取、简化代码管理、以及更安全的异步任务管理等方面。以下是 std::future 的一些主要优势:
1. 自动结果获取与同步
std::future提供了一种便捷的机制来获取异步任务的返回值。当我们使用线程时,通常无法轻松获得线程的返回值,线程函数如果有返回值,需要通过共享变量、全局变量或其他同步机制进行通信,这使得代码更加复杂。通过
std::future,可以轻松获取异步任务的结果,它在内部同步管理任务执行的结果。例子:
#include <iostream>
#include <future> int compute() {
return 42;
} int main() {
std::future<int> result = std::async(std::launch::async, compute);
std::cout << "Result: " << result.get() << std::endl; // 自动等待线程完成并返回结果
return 0;
}
在这种情况下,
result.get()会等待线程完成,并获取异步任务的返回值42。这比直接使用线程共享状态的方式要简单得多。
2. 简化代码管理
使用
std::thread需要手动管理线程的生命周期,比如使用join()来等待线程执行完成。而std::future通过get()或者wait()来等待任务完成,自动管理同步,不需要手动调用join()。直接使用线程时:
#include <iostream>
#include <thread> void compute(int &result) {
result = 42;
} int main() {
int result;
std::thread t(compute, std::ref(result));
t.join(); // 必须手动调用 join() 等待线程完成
std::cout << "Result: " << result << std::endl;
return 0;
}
这里要通过
std::ref(result)共享数据,并且必须手动管理线程的结束 (join()),否则程序会发生错误。
3. 更安全的异步任务管理
std::future和std::async可以更好地管理异步任务,避免直接操作线程带来的错误。比如,当线程没有被正确join时,程序可能崩溃,而std::future会自动等待异步任务完成。如果程序异常退出或者忘记调用
join(),std::thread会导致程序中断或者未定义行为。而std::future不会发生这些问题,它通过get()自动等待异步任务完成。例如,如果使用
std::thread,忘记join(),程序会出现崩溃风险:std::thread t([] { std::this_thread::sleep_for(std::chrono::seconds(1)); });
// 如果没有 t.join(),程序将崩溃
4. 异常管理
std::future可以捕获异步任务中的异常,而直接使用线程时,异常管理需要额外的工作。在std::future中,get()不仅可以获取任务的结果,还可以在任务中出现异常时,将该异常抛出,方便后续处理。例子:
#include <iostream>
#include <future>
#include <stdexcept> int faulty_task() {
throw std::runtime_error("Something went wrong!");
} int main() {
std::future<int> result = std::async(std::launch::async, faulty_task);
try {
int value = result.get(); // 在此捕获异常
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
直接使用
std::thread时,要处理任务中的异常需要复杂的机制,std::future简化了这一过程。
5. 延迟启动任务
使用
std::async和std::future,你可以选择是否立即启动线程,或者延迟执行任务(惰性启动)。通过std::async的第二个参数(如std::launch::deferred),可以控制任务是否异步执行或延迟执行,这种灵活性在直接使用线程时无法轻易实现。惰性启动:
std::future<int> result = std::async(std::launch::deferred, compute); // 任务并不会立即执行
// result.get() 执行时,任务才开始执行
总结
std::future 的主要优势在于:
- 简化了异步任务的结果获取与同步操作;
- 提供了更好的异常管理;
- 避免了手动管理线程生命周期的复杂性;
- 提供了延迟执行(deferred execution)的灵活性。
相比之下,std::thread 直接操作线程,虽然可以让程序员显式控制任务,但在实际开发中,这种显式控制常常导致复杂的代码管理和更大的错误风险,因此 std::future 是一种更高层次、更安全的选择。
`std::future`--异步的优势的更多相关文章
- C++11之std::future和std::promise
为什么C++11引入std::future和std::promise?C++11创建了线程以后,我们不能直接从thread.join()得到结果,必须定义一个变量,在线程执行时,对这个变量赋值,然后执 ...
- C++11之std::future和std::promise和std::std::packaged_task
为什么C++11引入std::future和std::promise?C++11创建了线程以后,我们不能直接从thread.join()得到结果,必须定义一个变量,在线程执行时,对这个变量赋值,然后执 ...
- C++并发高级接口:std::async和std::future
std::async和std::future std::async创建一个后台线程执行传递的任务,这个任务只要是callable object均可,然后返回一个std::future.future储存 ...
- C++11 使用异步编程std::async和std::future
先说明一点:std::asyanc是std::future的高级封装, 一般我们不会直接使用std::futrue,而是使用对std::future的高级封装std::async. 下面分别说一下. ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- C++并发编程之std::async(), std::future, std::promise, std::packaged_task
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- C++并发编程之std::future
简单地说,std::future 可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段.std::future 通常由某个 Provider 创建,你可以把 Provider 想象成 ...
- 【C++并发实战】(三) std::future和std::promise
std::future和std::promise std::future std::future期待一个返回,从一个异步调用的角度来说,future更像是执行函数的返回值,C++标准库使用std::f ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)(转)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- 第27课 “共享状态”及其管理者(std::future/std::shared_future)
一. “共享状态” (一)“共享状态”对象 1. 用于保存线程函数及其参数.返回值以及新线程状态等信息.该对象通常创建在堆上,由std::async.std::promise和std::package ...
随机推荐
- Python用shp文件裁剪多个遥感影像的方法
本文介绍基于Python中ArcPy模块,基于矢量数据范围,对大量栅格遥感影像加以批量裁剪掩膜的方法. 首先,话不多说,本文所需要的代码如下所示. # -*- coding: utf-8 -* ...
- 6、Git之团队协作机制
6.1.团队内协作 6.1.1.创建本地库 如上图所示,一个名叫刘备的人,在本地电脑中创建了一个项目,并使用 git 来维护. 6.1.2.推送本地库到代码托管中心 如上图所示,刘备想让别人也能看到自 ...
- 【MongoDB】Re04 副本集 ReplicationSet
MongoDB中的副本集(Replica Set)是一组维护相同数据集的mongod服务. 副本集可提供冗余和高 可用性,是所有生产部署的基础. 也可以说,副本集类似于有自动故障恢复功能的主从集群.通 ...
- 【SVN】提交失败报错
SVN提交失败: 最后信息是提示 请输入日志消息,至少需要20个字符,提交终止 问题原因是: 提交的时候不要把提交信息换行来写,SVN只会读取第一行内容 如果消息没有问题还提交失败,可能是文件因为提交 ...
- 家庭局域网中电脑唤醒 —— WOL远程唤醒(python实现)
相关: https://blog.csdn.net/hih30250/article/details/136342258 在WOL介绍里说过WOL数据包的最简格式是由6个字节的255和目标计算机的48 ...
- 一个疑问:foundation models , 现在已经有了视觉的大模型也有了语言大模型,那么什么时候会有强化学习大模型,更准确的说什么时候会有强化学习的基础模型(foundation models)
一个疑问:foundation models , 现在已经有了视觉的大模型也有了语言大模型,那么什么时候会有强化学习大模型,更准确的说什么时候会有强化学习的基础模型(foundation models ...
- AI4Science 再填新成员:谷歌推出天气模型MetNet-3 已落地相关产品、谷歌天气预报模型GraphCast登刊Science —— AI天气预报大模型
相关: https://zhidx.com/news/40169.html https://zhidx.com/news/40290.html PS. 要知道,华为公司的最高学术成果就是AI天气预报, ...
- Linux中scanf类型匹配错误,特指scanf("%d", &c ) ,导致死循环的解决方法 —— fflush(stdin)和getchar()的使用
如题,朋友领导的孩子大学作业是个C语言编写的管理信息系统发来要我给改改,原代码的配置环境是Windows的C环境,由于10多年没有搞过Windows下的C语言了于是换上了Ubuntu18.04的系统上 ...
- 安装python库roboschool运行报错:ImportError: libpcre16.so.3: cannot open shared object file——解决方法
如题: 运行roboschool运行报错. 操作系统: Ubuntu ImportError: libpcre16.so.3: cannot open shared object file: No s ...
- 如何在vscode中支持python的annotation(注解,type checking)——通过设置pylance参数实现python注解的type checking
pylance是vscode的python官方插件的捆绑体,如何在vscode中安装python插件这里不介绍了.pylance的默认设置是不支持python的annotation的,需要我们手动设置 ...