我们应该如何向一个需要结果的任务引入 future?又如何向一个生成结果的线程引入对应的 promise呢?标准库提供了 packaged_task类型简化任务连接 future和 promise的设置。 packaged_task提供了一层包装代码,负责把某个任务的返回值或异常放入一个 promise中(就像5.3.5.1节中代码所做的那样)。如果通过调用 get_future(来向一个packaged_task发出请求,它会返回给你对应 promise的 future。例如,我们可以将两个任务连接起来,它们各自使用标准库 accumulate()(见3.4.2节和40.6节)算法将一个vector<double>中的一半元素累加起来:
double accum(double* beg,double* end,double init) //计算[beg:end)中元素的和,计算的初始值是init{return accumulate(beg,end,init);}double comp2(vector<double>& v){using Task_type=double(double*,duble*,double); //任务的类型packaged_task<Task_type> pt0{accum}; //打包任务(即accum)packaged_task<Task_type> pt1{accum};future<double> f0{pt0.get_future()}; //获取pt0的futurefuture<double> f1{pt1.get_future()}; //获取pt1的futuredouble* first=&v[0];thread t1{move(pt0),first,first+v.size()/2,0}; //为pt0启动一个线程thread t2{move(pt1),first+v.size()/2,first+v.size(),0}; //为pt1启动一个线程//...return f0.get()+f1.get(); //获得结果}
packaged_task模板接受模板参数表示任务的类型(本例中为 Task_type,即 double(``double* double*, double``)的别名),并接受构造函数参数作为任务(本例中为 accum)。因为 packaged_task不能被拷贝,所以move()操作是必需的。
请注意这段代码没有显式地使用锁:通过使用 packaged_task,我们可以集中精力于要完成的任务,而不必操心该如何管理它们之间的通信。两个任务运行于两个独立的线程,因此可以并行执行.
