一 简介
C++11中的std::async是个模板函数。std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待函数执行完成就可返回,返回结果是个std::future对象。函数返回的值可通过std::future对象的get成员函数获取。一旦完成函数的执行,共享状态将包含函数返回的值并ready。
允许调用者选择特定的启动策略,第一个参数是std::async的启动策略类型是个枚举类enum class launch,包括:
-
std::launch::async:异步,启动一个新的线程调用Fn,该函数由新线程异步调用,并且将其返回值与共享状态的访问点同步。
-
std::launch::deferred:延迟,在访问共享状态时该函数才被调用。对Fn的调用将推迟到返回的std::future的共享状态被访问时(使用std::future的wait或get函数)。
参数Fn:可以为函数指针、成员指针、任何类型的可移动构造的函数对象(即类定义了operator()的对象)。Fn的返回值或异常存储在共享状态中以供异步的std::future对象检索。
参数Args:传递给Fn调用的参数,它们的类型应是可移动构造的。
二 例子
std::launch::async:异步
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std::chrono;
std::string getData()
{
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return "Q是德华" ;
}
void breakCode()
{
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return ;
}
int main()
{
//获取开始时间
system_clock::time_point start = system_clock::now();
std::future<std::string> strFuSec = std::async(std::launch::async, getData);
breakCode();
//数据在future<std::string>对象中可获取之前,将一直阻塞
std::string strData = strFuSec.get();
//获取结束时间
auto end = system_clock::now();
auto diff = duration_cast<std::chrono::seconds>(end - start).count();
std::cout << "用时" << diff << "秒" << std::endl;
std::cout << strData << std::endl;
return 0;
}
结果
std::launch::deferred:延迟
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std::chrono;
std::string getData()
{
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return "Q是德华" ;
}
void breakCode()
{
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return ;
}
int main()
{
//获取开始时间
system_clock::time_point start = system_clock::now();
std::future<std::string> strFuSec = std::async(std::launch::deferred, getData);
breakCode();
//数据在future<std::string>对象中可获取之前,将一直阻塞
std::string strData = strFuSec.get();
//获取结束时间
auto end = system_clock::now();
auto diff = duration_cast<std::chrono::seconds>(end - start).count();
std::cout << "用时" << diff << "秒" << std::endl;
std::cout << strData << std::endl;
return 0;
}
结果
第一个参数如果不写,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch::deferred,或者是两者的任意组合,取决于它们的系统和特定库实现。vs是std::launch::deferred
lamda函数,第一个参数如果不写
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std::chrono;
int main()
{
//获取开始时间
system_clock::time_point start = system_clock::now();
std::future<std::string> strFuSec = std::async([]()->std::string {
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return "Q是德华";
});
[]()
{
//确保函数要5秒才能执行完成
std::this_thread::sleep_for(seconds(5));
return;
}();
//数据在future<std::string>对象中可获取之前,将一直阻塞
std::string strData = strFuSec.get();
//获取结束时间
auto end = system_clock::now();
auto diff = duration_cast<std::chrono::seconds>(end - start).count();
std::cout << "用时" << diff << "秒" << std::endl;
std::cout << strData << std::endl;
return 0;
}
结果