C++11 并发指南四(future 详解一 std::promise 介绍)
前面兩講《C++11 并發(fā)指南二(std::thread 詳解)》,《C++11 并發(fā)指南三(std::mutex 詳解)》分別介紹了 std::thread 和 std::mutex,相信讀者對 C++11 中的多線程編程有了一個最基本的認(rèn)識,本文將介紹 C++11 標(biāo)準(zhǔn)中 <future> 頭文件里面的類和相關(guān)函數(shù)。
<future> 頭文件中包含了以下幾個類和函數(shù):
- Providers 類:std::promise, std::package_task
- Futures 類:std::future, shared_future.
- Providers 函數(shù):std::async()
- 其他類型:std::future_error, std::future_errc, std::future_status, std::launch.
std::promise 類介紹
promise 對象可以保存某一類型 T 的值,該值可被 future 對象讀取(可能在另外一個線程中),因此 promise 也提供了一種線程同步的手段。在 promise 對象構(gòu)造時可以和一個共享狀態(tài)(通常是std::future)相關(guān)聯(lián),并可以在相關(guān)聯(lián)的共享狀態(tài)(std::future)上保存一個類型為 T 的值。
可以通過 get_future 來獲取與該 promise 對象相關(guān)聯(lián)的 future 對象,調(diào)用該函數(shù)之后,兩個對象共享相同的共享狀態(tài)(shared state)
- promise 對象是異步 Provider,它可以在某一時刻設(shè)置共享狀態(tài)的值。
- future 對象可以異步返回共享狀態(tài)的值,或者在必要的情況下阻塞調(diào)用者并等待共享狀態(tài)標(biāo)志變?yōu)?ready,然后才能獲取共享狀態(tài)的值。
下面以一個簡單的例子來說明上述關(guān)系
#include <iostream> // std::cout #include <functional> // std::ref #include <thread> // std::thread #include <future> // std::promise, std::futurevoid print_int(std::future<int>& fut) {int x = fut.get(); // 獲取共享狀態(tài)的值.std::cout << "value: " << x << '\n'; // 打印 value: 10. }int main () {std::promise<int> prom; // 生成一個 std::promise<int> 對象.std::future<int> fut = prom.get_future(); // 和 future 關(guān)聯(lián).std::thread t(print_int, std::ref(fut)); // 將 future 交給另外一個線程t.prom.set_value(10); // 設(shè)置共享狀態(tài)的值, 此處和線程t保持同步. t.join();return 0; }std::promise 構(gòu)造函數(shù)
| promise(); |
| template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc); |
| promise (const promise&) = delete; |
| promise (promise&& x) noexcept; |
另外,std::promise 的 operator= 沒有拷貝語義,即 std::promise 普通的賦值操作被禁用,operator= 只有 move 語義,所以 std::promise 對象是禁止拷貝的。
例子:
#include <iostream> // std::cout #include <thread> // std::thread #include <future> // std::promise, std::future std::promise<int> prom;void print_global_promise () {std::future<int> fut = prom.get_future();int x = fut.get();std::cout << "value: " << x << '\n'; }int main () {std::thread th1(print_global_promise);prom.set_value(10);th1.join();prom = std::promise<int>(); // prom 被move賦值為一個新的 promise 對象. std::thread th2 (print_global_promise);prom.set_value (20);th2.join();return 0; }?std::promise::get_future 介紹
該函數(shù)返回一個與 promise 共享狀態(tài)相關(guān)聯(lián)的 future 。返回的 future 對象可以訪問由 promise 對象設(shè)置在共享狀態(tài)上的值或者某個異常對象。只能從 promise 共享狀態(tài)獲取一個 future 對象。在調(diào)用該函數(shù)之后,promise 對象通常會在某個時間點(diǎn)準(zhǔn)備好(設(shè)置一個值或者一個異常對象),如果不設(shè)置值或者異常,promise 對象在析構(gòu)時會自動地設(shè)置一個 future_error 異常(broken_promise)來設(shè)置其自身的準(zhǔn)備狀態(tài)。上面的例子中已經(jīng)提到了 get_future,此處不再重復(fù)。
std::promise::set_value 介紹
| void set_value (const T& val); void set_value (T&& val); |
| void promise<R&>::set_value (R& val); // when T is a reference type (R&) void promise<void>::set_value (void); // when T is void |
設(shè)置共享狀態(tài)的值,此后 promise 的共享狀態(tài)標(biāo)志變?yōu)?ready.
?std::promise::set_exception 介紹
為 promise 設(shè)置異常,此后 promise 的共享狀態(tài)變標(biāo)志變?yōu)?ready,例子如下,線程1從終端接收一個整數(shù),線程2將該整數(shù)打印出來,如果線程1接收一個非整數(shù),則為 promise 設(shè)置一個異常(failbit) ,線程2 在std::future::get 是拋出該異常。
#include <iostream> // std::cin, std::cout, std::ios #include <functional> // std::ref #include <thread> // std::thread #include <future> // std::promise, std::future #include <exception> // std::exception, std::current_exceptionvoid get_int(std::promise<int>& prom) {int x;std::cout << "Please, enter an integer value: ";std::cin.exceptions (std::ios::failbit); // throw on failbittry {std::cin >> x; // sets failbit if input is not int prom.set_value(x);} catch (std::exception&) {prom.set_exception(std::current_exception());} }void print_int(std::future<int>& fut) {try {int x = fut.get();std::cout << "value: " << x << '\n';} catch (std::exception& e) {std::cout << "[exception caught: " << e.what() << "]\n";} }int main () {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread th1(get_int, std::ref(prom));std::thread th2(print_int, std::ref(fut));th1.join();th2.join();return 0; }std::promise::set_value_at_thread_exit 介紹
設(shè)置共享狀態(tài)的值,但是不將共享狀態(tài)的標(biāo)志設(shè)置為 ready,當(dāng)線程退出時該 promise 對象會自動設(shè)置為 ready。如果某個 std::future 對象與該 promise 對象的共享狀態(tài)相關(guān)聯(lián),并且該 future 正在調(diào)用 get,則調(diào)用 get 的線程會被阻塞,當(dāng)線程退出時,調(diào)用 future::get 的線程解除阻塞,同時 get 返回 set_value_at_thread_exit 所設(shè)置的值。注意,該函數(shù)已經(jīng)設(shè)置了 promise 共享狀態(tài)的值,如果在線程結(jié)束之前有其他設(shè)置或者修改共享狀態(tài)的值的操作,則會拋出 future_error( promise_already_satisfied )。
std::promise::swap 介紹
交換 promise 的共享狀態(tài)。
總結(jié)
以上是生活随笔為你收集整理的C++11 并发指南四(future 详解一 std::promise 介绍)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pt-find使用
- 下一篇: audio标签下方有空隙的原因与解决方法