std::packaged_task
包装一个可调用的对象,并且允许异步获取该可调用对象产生的结果,从包装可调用对象意义上来讲,std::packaged_task
与 std::function
类似,只不过 std::packaged_task
将其包装的可调用对象的执行结果传递给一个 std::future 对象(该对象通常在另外一个线程中获取 std::packaged_task
任务的执行结果)。
std::packaged_task
对象内部包含了两个最基本元素:
- 被包装的任务(stored task),任务(task)是一个可调用的对象,如函数指针、成员函数指针或者函数对象;
- 共享状态(shared state),用于保存任务的返回值,可以通过
std::future
对象来达到异步访问共享状态的效果。
可以通过 std::packged_task::get_future
来获取与共享状态相关联的 std::future
对象。在调用该函数之后,两个对象共享相同的共享状态,具体解释如下:
std::packaged_task
对象是异步 Provider,它在某一时刻通过调用被包装的任务来设置共享状态的值。std::future
对象是一个异步返回对象,通过它可以获得共享状态的值,当然在必要的时候需要等待共享状态标志变为 ready.
std::packaged_task
的共享状态的生命周期一直持续到最后一个与之相关联的对象被释放或者销毁为止。下面一个小例子大致讲了 std::packaged_task
的用法:
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, int to) {
for (int i=from; i!=to; --i) {
std::cout << i << '\n';
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Finished!\n";
return from - to;
}
int main ()
{
std::packaged_task<int(int,int)> task(countdown); // 设置 packaged_task
std::future<int> ret = task.get_future(); // 获得与 packaged_task 共享状态相关联的 future 对象.
std::thread th(std::move(task), 10, 0); //创建一个新线程完成计数任务.
int value = ret.get(); // 等待任务完成并获取结果.
std::cout << "The countdown lasted for " << value << " seconds.\n";
th.join();
return 0;
}
std::packaged_task 构造函数
packaged_task() noexcept;
//default 默认构造函数,初始化一个空的共享状态,并且该 packaged_task 对象无包装任务。
template <class Fn>
explicit packaged_task (Fn&& fn);
// initialization 初始化一个共享状态,并且被包装任务由参数 fn 指定。
template <class Fn, class Alloc>
explicit packaged_task (allocator_arg_t aa, const Alloc& alloc, Fn&& fn);
// with allocator 带自定义内存分配器的构造函数,与默认构造函数类似,但是使用自定义分配器来分配共享状态。
packaged_task (const packaged_task&) = delete;
// copy [deleted] 拷贝构造函数,被禁用。
packaged_task (packaged_task&& x) noexcept;
// move 移动构造函数。
下面例子介绍了各类构造函数的用法:
#include <iostream> // std::cout
#include <utility> // std::move
#include <future> // std::packaged_task, std::future
#include <thread> // std::thread
int main ()
{
std::packaged_task<int(int)> foo; // 默认构造函数.
// 使用 lambda 表达式初始化一个 packaged_task 对象.
std::packaged_task<int(int)> bar([](int x){return x*2;});
foo = std::move(bar); // move-赋值操作,也是 C++11 中的新特性.
// 获取与 packaged_task 共享状态相关联的 future 对象.
std::future<int> ret = foo.get_future();
std::thread(std::move(foo), 10).detach(); // 产生线程,调用被包装的任务.
int value = ret.get(); // 等待任务完成并获取结果.
std::cout << "The double of 10 is " << value << ".\n";
return 0;
}
标签:std,task,对象,packaged,future,构造函数 From: https://www.cnblogs.com/love-9/p/18096386