std::packaged_task
https://www.cnblogs.com/haippy/p/3279565.html
https://en.cppreference.com/w/cpp/thread/packaged_task
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.
#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; }