std::future的基本用法

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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容