類模板
<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.