浅谈C++11 std::async()基础用法示例
作者:华丽的周遭
在 C++11 中引入的 std::async是一个用于异步执行任务的工具,它简化了多线程编程的复杂度,通过返回 std::future对象实现对异步任务结果的获取。
一、核心概念
std::async用于启动一个异步任务(可能在独立线程中执行),并返回一个 std::future对象,通过该对象可以:
- 阻塞等待任务完成并获取返回值(
future::get()); - 查询任务状态(
future::valid()、future::wait_for()等); - 异常传递(任务中的异常会延迟到
get()时抛出)。
二、函数原型与启动策略
std::async的声明如下:
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( std::launch policy, Function&& f, Args&&... args );其中第二个模板参数是启动策略(std::launch枚举),控制任务的执行方式:
策略 | 说明 |
|---|---|
std::launch::async | 强制在新线程中异步执行任务(类似 std::thread直接启动)。 |
std::launch::deferred | 延迟执行:任务不会立即启动,直到调用 future.get()或 wait()时才在当前线程同步执行。 |
默认策略(无显式指定) | 实现定义(通常是 `async |
三、基础用法示例
1. 最简用法(无显式策略)
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( std::launch policy, Function&& f, Args&&... args );std::async(compute, 2, 3)启动异步任务,传递函数compute和参数2, 3。future.get()阻塞主线程,直到任务完成并返回结果。
2. 显式指定启动策略
// 强制异步执行(新线程) auto future_async = std::async(std::launch::async, compute, 2, 3); // 延迟执行(当前线程同步执行) auto future_deferred = std::async(std::launch::deferred, compute, 2, 3); future_async.get(); // get()阻塞等待 future_deferred.get(); // 此时在当前线程同步执行 compute(2,3)
四、参数传递与引用语义
std::async支持传递任意可调用对象(函数、Lambda、函数对象等)和参数。若需传递引用,需用 std::ref包装:
#include <functional>
void modify(int& value) {
value = 100;
}
int main() {
int x = 0;
// 错误:直接传递引用会被复制(值语义)
// auto future = std::async(modify, x);
// 正确:用 std::ref 传递引用
auto future = std::async(modify, std::ref(x));
future.get();
std::cout << x << std::endl; // 输出 100(x 被修改)
return 0;
}五、std::future 的常用接口
std::async返回的 std::future提供以下关键方法:
方法 | 说明 |
|---|---|
get() | 阻塞直到任务完成,返回结果(或抛出任务中的异常);只能调用一次。 |
wait() | 阻塞直到任务完成;可多次调用。 |
wait_for(timeout) | 阻塞最多 timeout时间,返回 std::future_status(ready/timeout/deferred)。 |
wait_until(timepoint) | 阻塞直到指定时间点。 |
valid() | 检查 future是否关联有效结果(未调用 get()时为 true)。 |
share() | 转换为 std::shared_future(允许多个对象共享结果)。 |
六、异常处理
异步任务中抛出的异常会被 std::future捕获,直到调用 get()时重新抛出:
int risky_compute(int x) {
if (x < 0) throw std::runtime_error("x is negative");
return x * 2;
}
int main() {
auto future = std::async(risky_compute, -1);
try {
int result = future.get(); // 抛出 std::runtime_error
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << ""; // 捕获异常
}
return 0;
}七、注意事项
生命周期管理:
std::future析构时,若任务未完成且未被get()或wait(),可能导致程序终止(取决于实现)。若需共享结果,使用std::shared_future。线程复用:
std::async不保证任务一定在新线程中执行(尤其是deferred策略或编译器优化),依赖具体实现。性能开销:
相比手动管理
std::thread,std::async自动管理线程生命周期,但频繁创建小任务可能有额外开销(适合中高耗时任务)。
八、典型应用场景
- 并行计算:同时执行多个独立任务(如图像处理中的多区域计算)。
- 异步IO:发起IO操作后异步等待结果,避免阻塞主线程。
- 任务编排:结合
std::future::wait_for实现超时控制(如监控任务是否超时)。
总结
std::async是 C++11 中简化异步编程的核心工具,通过 std::future提供结果获取和状态查询能力。合理使用其启动策略和异常处理机制,可有效提升代码的并发性能和可维护性。
到此这篇关于浅谈C++11 std::async()基础用法示例的文章就介绍到这了,更多相关C++11 std::async()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
