std::future
- 提供了一種訪問異步操作結(jié)果的機制;
- 可以從將來時間獲取結(jié)果,可以通過查詢狀態(tài)獲知執(zhí)行情況,也可以阻塞獲取異步執(zhí)行的結(jié)果
enum class future_status { // names for timed wait function returns ready,//異步操作已經(jīng)完成 timeout,//異步操作超時 deferred//異步操作還沒開始 }; - future的結(jié)果獲取或狀態(tài)查詢有如下四種方法:
_Ty get();//一直等待條件變量通知,將結(jié)果返回
void wait() const;//一直等待條件變量通知
_Future_status wait_for;//等待時間段,調(diào)用條件變量的wait_for(),根據(jù)條件變量的返回結(jié)果來返回
_Future_status wait_until;//等待到一個絕對時間點
std::promise
- promise中 構(gòu)造和賦值運算符是被禁用的,保留了右值引用的構(gòu)造和移動賦值;
- 提供了異步操作結(jié)果的存儲,和future對應(yīng);
- 可以將可執(zhí)行的對象委托給promise異步或同步執(zhí)行,并保證再結(jié)果執(zhí)行結(jié)束后,可以通過promise中獲取的future,去promise對象中獲取執(zhí)行結(jié)果
promise(promise&& _Other) _NOEXCEPT; promise& operator=(promise&& _Other) _NOEXCEPT promise(const promise&) = delete; promise& operator=(const promise&) = delete; - 成員函數(shù)介紹
void swap(promise& _Other) _NOEXCEPT; //交換引用的狀態(tài) future<_Ty> get_future();//獲取和promise共同引用同一個狀態(tài)的future void set_value(const _Ty& _Val);//設(shè)置引用狀態(tài)的值,此后狀態(tài)標志變?yōu)閞eady,通知互斥變量可用,future返回值 void set_value_at_thread_exit(const _Ty& _Val);//設(shè)置引用狀態(tài)的值,不將狀態(tài)標志設(shè)置為ready,等待線程結(jié)束(如果已經(jīng)被設(shè)置過值,會拋異常future_errc::promise_already_satisfied) void set_exception(_XSTD exception_ptr _Exc);//設(shè)置異常,將狀態(tài)標志ready置為true
std::packaged_task
packaged_task 本質(zhì)是對promise的封裝
封裝了可執(zhí)行對象和對象執(zhí)行結(jié)果
獲取promise對應(yīng)的future,作為獲取值的依據(jù)
-
構(gòu)造函數(shù)需要顯示調(diào)用
template<class _Fty2, class = typename enable_if< !is_same<typename decay<_Fty2>::type, _Myt>::value>::type> explicit packaged_task(_Fty2&& _Fnarg) : _MyPromise(new _MyStateType(_STD forward<_Fty2>(_Fnarg))) { // construct from rvalue function object } 和promise類似,只不過promise是對引用狀態(tài)的狀態(tài)和結(jié)果的保存和設(shè)置,pakaged_task是對引用狀態(tài)內(nèi)使用函數(shù)的設(shè)置;
std::async
async將異步操作封裝起來
根據(jù)入?yún)㈩愋蛣?chuàng)建不同的任務(wù),包括創(chuàng)建異步執(zhí)行、推遲執(zhí)行和同步執(zhí)行操作;
推遲的異步操作需要future.wait()觸發(fā)并等待執(zhí)行結(jié)束;
-
類型如下
enum class launch { // names for launch options passed to async async = 0x1, deferred = 0x2 }; -
本質(zhì)為在創(chuàng)建可執(zhí)行的異步任務(wù)(packaged_task的功能)外,增加任務(wù)的開啟方式的處理;
- 是個語法糖;
- 是整合了packaged_task的操作過程;
- 等價于創(chuàng)建任務(wù)+任務(wù)執(zhí)行方式選;
-
Demo如下:
#include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <future> #include <string> #include <mutex> std::mutex m; struct X { void foo(int i, const std::string& str) { std::lock_guard<std::mutex> lk(m); std::cout << str << ' ' << i << '\n'; } void bar(const std::string& str) { std::lock_guard<std::mutex> lk(m); std::cout << str << '\n'; } int operator()(int i) { std::lock_guard<std::mutex> lk(m); std::cout << i << '\n'; return i + 10; } }; template <typename RandomIt> int parallel_sum(RandomIt beg, RandomIt end) { auto len = end - beg; if (len < 1000) return std::accumulate(beg, end, 0); RandomIt mid = beg + len / 2; auto handle = std::async(std::launch::async, parallel_sum<RandomIt>, mid, end); int sum = parallel_sum(beg, mid); return sum + handle.get(); } int main() { std::vector<int> v(10000, 1); std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n'; X x; // Calls (&x)->foo(42, "Hello") with default policy: // may print "Hello 42" concurrently or defer execution auto a1 = std::async(&X::foo, &x, 42, "Hello"); // Calls x.bar("world!") with deferred policy // prints "world!" when a2.get() or a2.wait() is called auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!"); // Calls X()(43); with async policy // prints "43" concurrently auto a3 = std::async(std::launch::async, X(), 43); a2.wait(); // prints "world!" std::cout << a3.get() << '\n'; // prints "53" } // if a1 is not done at this point, destructor of a1 prints "Hello 42" here
類圖如下
【。。?!?/p>