簡單地說,std::future 可以用來獲取異步任務的結果,因此可以把它當成一種簡單的線程間同步的手段。std::future 通常由某個 Provider 創建,你可以把 Provider 想象成一個異步任務的提供者,Provider 在某個線程中設置共享狀態的值,與該共享狀態相關聯的 std::future 對象調用 get(通常在另外一個線程中) 獲取該值,如果共享狀態的標志不為 ready,則調用 std::future::get 會阻塞當前的調用者,直到 Provider 設置了共享狀態的值(此時共享狀態的標志變為 ready),std::future::get 返回異步任務的值或異常(如果發生了異常)。
一個有效(valid)的 std::future 對象通常由以下三種 Provider 創建,並和某個共享狀態相關聯。Provider 可以是函數或者類,其實我們前面都已經提到了,他們分別是:
- std::async 函數。
- std::promise::get_future,get_future 為 promise 類的成員函數。
- std::packaged_task::get_future,此時 get_future為 packaged_task 的成員函數。
一個 std::future 對象只有在有效(valid)的情況下才有用(useful),由 std::future 默認構造函數創建的 future 對象不是有效的(除非當前非有效的 future 對象被 move 賦值另一個有效的 future 對象)。
在一個有效的 future 對象上調用 get 會阻塞當前的調用者,直到 Provider 設置了共享狀態的值或異常(此時共享狀態的標志變為 ready),std::future::get 將返回異步任務的值或異常(如果發生了異常)。
// future example #include <iostream> // std::cout #include <future> // std::async, std::future #include <chrono> // std::chrono::milliseconds // a non-optimized way of checking for prime numbers: bool is_prime(int x) { for (int i = 2; i < x; ++i) if (x % i == 0) return false; return true; } int main() { // call function asynchronously: std::future < bool > fut = std::async(is_prime, 444444443); // do something while waiting for function to set future: std::cout << "checking, please wait"; std::chrono::milliseconds span(100); while (fut.wait_for(span) == std::future_status::timeout) std::cout << '.'; bool x = fut.get(); // retrieve return value std::cout << "\n444444443 " << (x ? "is" : "is not") << " prime.\n"; return 0; }