类模板
<future>

std::packaged_task

template <class T> packaged_task;     // undefinedtemplate <class Ret, class... Args> class packaged_task<Ret(Args...)>;
Packaged task
一个 packaged_task 包装了一个 *可调用元素*,并允许异步地检索其结果。

它类似于 std::function,但会自动将其结果传递给一个 future 对象。

该对象内部包含两个元素:
  • 一个*存储的任务*,这是一个*可调用对象*(例如函数指针、指向成员的指针或函数对象),其*调用签名*应接受 Args... 类型的值作为参数,并返回 Ret 类型的值。
  • 一个*共享状态*,它能够存储调用*存储的任务*(Ret 类型)的结果,并通过一个 future 异步访问。

通过调用成员函数 get_future 将*共享状态*与 future 对象关联起来。调用之后,这两个对象共享相同的*共享状态*。
- packaged_task 对象是*异步提供者*,它将在某个时候通过*调用*(operator())*存储的任务*来设置*共享状态*为就绪状态。
- future 对象是*异步返回对象*,它可以检索*共享状态*的值,必要时会等待其就绪。

如果*共享状态*与多个对象关联,则其生命周期至少持续到最后一个关联对象释放它或被销毁为止。因此,如果它也与 future 关联,它可以比最初获取它的 packaged_task 对象存活更久。

成员函数


非成员函数重载


非成员类特化


示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// packaged_task example
#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 << "Lift off!\n";
  return from-to;
}

int main ()
{
  std::packaged_task<int(int,int)> tsk (countdown);   // set up packaged_task
  std::future<int> ret = tsk.get_future();            // get future

  std::thread th (std::move(tsk),10,0);   // spawn thread to count down from 10 to 0

  // ...

  int value = ret.get();                  // wait for the task to finish and get result

  std::cout << "The countdown lasted for " << value << " seconds.\n";

  th.join();

  return 0;
}

可能的输出

10
9
8
7
6
5
4
3
2
1
Lift off!
The countdown lasted for 10 seconds.