1. 前言
packaged_task是C++用来实现异步调用的特性之一,其用来包装函数使其作为异步任务进行。最后函数的返回值可以通过该packaged_task的future对象来获得。
2.1代码实例如下
// Copyright [2021], [Ziliu]
#include <functional> // std::ref
#include <future> // std::promise std::future
#include <iostream>
#include <numeric> // std::accumulate
#include <thread>
#include <vector>
using namespace std;
double Accum(const double* beg, const double* end, double init) {
// accumulate包含在头文件numeric中
// accumulate:计算[beg:end)中元素的和,计算的初始值是init
return accumulate(beg, end, init);
}
double Comp2(const vector<double>& v) {
// 重定义任务类型
using Task_type = double(const double*,const double*,double);
// 1. 创建封装回调函数的packaged_task<>
packaged_task<Task_type> ptO(accum);
packaged_task<Task_type> pt1(accum);//打包任务(即accum)
// 2.获得相应packaged_task的future对象
future<double> fO = ptO.get_future();//获取ptO的future
future<double> f1 = pt1.get_future();//获取pt1的future
const double* first = &v[0];
// 3.为pt0和pt1定义一个线程
thread t1(ref(ptO),first,first+v.size()/2,0);
thread t2(ref(pt1),first+v.size()/2,first+v.size(),0);
// 4.线程启动
t1.join();
t2.join();
// 5.通过future对象的get()函数获得结果
return fO.get() + f1.get();
}
int main() {
// 初始化数组
vector<double> arr{1,2,3,4};
// 调用packaged_task封装的函数
int result = Comp2(arr);
std::cout << result << std::endl;
return 0;
}
2.2 在packaged_task中使用lambda表达式包装函数
// Copyright [2021], [ziliu]
#include <algorithm>
#include <functional> // std::ref
#include <future>
#include <iostream>
#include <thread>
// 计算数值相加
int Add(const int& a, const int& b) {
return a + b;
}
// 使用packaged_task<>创建异步任务
// std::packaged_task<>可以包装一个标准函数,使其适用于作为异步功能运行。
// 最后函数的返回值可以通过该task的future对象来获得
int main() {
// 使用lambda表达式
// 1. 创建封装回调函数的packaged_task<>
std::packaged_task<int(const int&, const int&)> task2([](const int& a, const int& b){
return a + b;
});
// 2. 从packaged_task<>获取相关的future<>
std::future<int> result2 = task2.get_future();
// 3. 将packaged_task传递给线程以异步运行
// std::thread th(std::move(task), 1, 2);
std::thread th2(std::ref(task2), 1, 2);
// 4. join线程,阻塞直到线程完成时返回
th2.join();
// 5. 获取packaged_task<>的结果,即Add()的返回值
int count2 = result2.get();
std::cout << count2 << std::endl;
return 0;
}