在项目中,难免遇到性能问题,为了提高处理的性能,针对可以并行处理的部分单独提取出来,利用并行编程来提高处理的速度,从而实现高性能。C++11中有一个async()函数,非常方便的实现异步处理。
每次调用async()函数,会自动创建一个线程来进行处理,并返回一个future<> 未来变量,根据future变量,可以获取返回值。
async函数解析
函数原型如下:
/// Launch code for futures
enum class launch
{
async = 1,
deferred = 2
};
template<typename _Fn, typename... _Args>
using __async_result_of = typename result_of<
typename decay<_Fn>::type(typename decay<_Args>::type...)>::type;
template<typename _Fn, typename... _Args>
future<__async_result_of<_Fn, _Args...>>
async(launch __policy, _Fn&& __fn, _Args&&... __args);
1、入参
1.1 launch __policy 异步处理的策略,包括两种: async 和 deferred
async = 1, // 调用async函数的时候就已经运行程序了
deferred = 2 // 延迟运行,当返回的future调用get函数时开始运行异步处理函数。
1.2 _Fn&& __fn 异步处理的函数
1.3 _Args&&… __args 异步处理函数的输入参数。
简单的函数模型为: async(异步策略, 异步处理函数(lamda表达式比较方便), 异步处理函数的参数)
int func(int a) {
std::cout<<a;
return a+1;
}
future<int> fu = async(std::launch::async, func, 1000);
2、返回结果
2.1 返回结果为 future 变量,这里的type跟异步处理函数的返回值类型保持一致,例如:
int funcInt(int a) {
std::cout<<a;
return a+1;
}
void funcVoid(int a) {
std::cout<<a;
return;
}
future<int> fu = async(std::launch::async, funcInt, 1000);
future<void> fu = async(std::launch::async, funcVoid, 1000);
当policy 设置为deferred 时,返回的future实例调用get函数,此时异步处理才开始例如:
future<int> fu = async(std::launch::deferred, funcInt, 1000);
future<void> fu2 = async(std::launch::async, funcVoid, 1000); // 此时funcVoid函数开始运行
int ret = fu2.get(); // 运行到这里,funcInt()函数才开始运行
fu.wait(); // 等待funcVoid函数运行完成
async实现异步处理
实例:当前有一个vector向量,长度为10000,处理器是4核,需要将10000个数据拷贝到一个数组中。
void dataCopy(vector<int> &src, int *dst, int dstLen) {
int len = src.length();
int threadNum = 4;
future<void> futureList[threadNum]; // 定义一个future<void> 数组,用来存放async返回值,这里的void是异步函数的返回类型。
for (int i = 0; i < threadNum; i++) { // for循环对每个线程启动async处理
futureList[i] = std::async(std::launch::async, [&](int start, int end) { // policy是async,代表程序运行到这个地方,就已经开始运行后面的lamda表达式了
for (int j = start; j < end; j++) {
dst.at(j) = src.at(j);
}
}, i * len / threadNum, (i + 1) * len / threadNum); // 后面这两个是lamda表达式的输入参数。
}
for (int i = 0; i < threadNum; i++) {
futureList[i].wait(); // 等待所有线程结束
}
return;
}