前言
std::async是C++11新增的一个功能,它主要提供了一种方便的方式来执行异步任务。std::async函数模板会返回一个std::future对象,该对象表示异步任务的执行结果。
基本用法
函数原型
std::future<T> async( std::launch policy, Function f, Args... args );
std::launch policy
:这是一个可选参数,用于指定异步任务的启动策略。它可以是std::launch::async
(尽可能异步执行),std::launch::deferred
(延迟执行,直到调用std::future::get
或std::future::wait
),或者两者的按位或组合(尽管在实践中,组合通常不被推荐,因为行为可能因实现而异)。如果不指定,则使用std::launch::async | std::launch::deferred
。Function f
:要异步执行的函数或可调用对象。Args... args
:传递给函数的参数。
返回值
std::async返回值是一个[[C++ 异步任务执行结果future]]]对象
std::future是一个模板类:
tempalte<class T>
std::future<T>
数据类型T 取决于异步函数的返回值类型
使用示例
调用普通函数
#include <iostream>
#include <future>
#include <chrono>
int compute(int x)
{ std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作 return x * 2;
} int main()
{ // 启动异步任务 auto future = std::async(std::launch::async, compute, 42); // 获取异步操作的结果int result = future.get(); // 阻塞直到异步操作完成,并获取结果 std::cout << "The result is " << result << std::endl;
return 0;
调用类成员函数
使用std::bind
#include <future>
#include <iostream>
#include <thread>
#include <utility>class MyClass {
public:int add(int a, int b) {std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作return a + b;}
};int main() {MyClass obj;// 使用 std::bind 绑定成员函数和对象实例auto async_result = std::async(std::launch::async,std::bind(&MyClass::add, &obj, 10, 20));// 等待结果完成int result = async_result.get();std::cout << "Result: " << result << std::endl;return 0;
}
使用lambda
#include <future>
#include <iostream>
#include <thread>
#include <utility>class MyClass {
public:int add(int a, int b) {std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作return a + b;}
};int main() {MyClass obj;// 使用 lambda 捕获对象实例,并调用成员函数auto async_result = std::async(std::launch::async,[&obj]() {return obj.add(10, 20);});// 等待结果完成int result = async_result.get();std::cout << "Result: " << result << std::endl;return 0;
}
注意事项
- std::async异常抛出:如果异步任务抛出异常,该异常会被储存在返回值std::future对象中,只有调用get()时,才会在本线程抛出。
- 返回值std::future对象应该使用std::move来移动std::future内的数据,而不是复制。