鍍金池/ 教程/ C/ D.4 <future>頭文件
3.4 本章總結(jié)
6.3 基于鎖設(shè)計(jì)更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
6.1 為并發(fā)設(shè)計(jì)的意義何在?
5.2 <code>C++</code>中的原子操作和原子類型
A.7 自動(dòng)推導(dǎo)變量類型
2.1 線程管理的基礎(chǔ)
8.5 在實(shí)踐中設(shè)計(jì)并發(fā)代碼
2.4 運(yùn)行時(shí)決定線程數(shù)量
2.2 向線程函數(shù)傳遞參數(shù)
第4章 同步并發(fā)操作
2.3 轉(zhuǎn)移線程所有權(quán)
8.3 為多線程性能設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)
6.4 本章總結(jié)
7.3 對(duì)于設(shè)計(jì)無(wú)鎖數(shù)據(jù)結(jié)構(gòu)的指導(dǎo)建議
關(guān)于這本書(shū)
A.1 右值引用
2.6 本章總結(jié)
D.2 &lt;condition_variable&gt;頭文件
A.6 變參模板
6.2 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)
4.5 本章總結(jié)
A.9 本章總結(jié)
前言
第10章 多線程程序的測(cè)試和調(diào)試
5.4 本章總結(jié)
第9章 高級(jí)線程管理
5.1 內(nèi)存模型基礎(chǔ)
2.5 識(shí)別線程
第1章 你好,C++的并發(fā)世界!
1.2 為什么使用并發(fā)?
A.5 Lambda函數(shù)
第2章 線程管理
4.3 限定等待時(shí)間
D.3 &lt;atomic&gt;頭文件
10.2 定位并發(fā)錯(cuò)誤的技術(shù)
附錄B 并發(fā)庫(kù)的簡(jiǎn)單比較
5.3 同步操作和強(qiáng)制排序
A.8 線程本地變量
第8章 并發(fā)代碼設(shè)計(jì)
3.3 保護(hù)共享數(shù)據(jù)的替代設(shè)施
附錄D C++線程庫(kù)參考
第7章 無(wú)鎖并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
D.7 &lt;thread&gt;頭文件
D.1 &lt;chrono&gt;頭文件
4.1 等待一個(gè)事件或其他條件
A.3 默認(rèn)函數(shù)
附錄A 對(duì)<code>C++</code>11語(yǔ)言特性的簡(jiǎn)要介紹
第6章 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
封面圖片介紹
7.2 無(wú)鎖數(shù)據(jù)結(jié)構(gòu)的例子
8.6 本章總結(jié)
8.1 線程間劃分工作的技術(shù)
4.2 使用期望等待一次性事件
8.4 設(shè)計(jì)并發(fā)代碼的注意事項(xiàng)
D.5 &lt;mutex&gt;頭文件
3.1 共享數(shù)據(jù)帶來(lái)的問(wèn)題
資源
9.3 本章總結(jié)
10.3 本章總結(jié)
10.1 與并發(fā)相關(guān)的錯(cuò)誤類型
D.4 &lt;future&gt;頭文件
3.2 使用互斥量保護(hù)共享數(shù)據(jù)
9.1 線程池
1.1 何謂并發(fā)
9.2 中斷線程
4.4 使用同步操作簡(jiǎn)化代碼
A.2 刪除函數(shù)
1.3 C++中的并發(fā)和多線程
1.4 開(kāi)始入門(mén)
第5章 C++內(nèi)存模型和原子類型操作
消息傳遞框架與完整的ATM示例
8.2 影響并發(fā)代碼性能的因素
7.1 定義和意義
D.6 &lt;ratio&gt;頭文件
A.4 常量表達(dá)式函數(shù)
7.4 本章總結(jié)
1.5 本章總結(jié)
第3章 線程間共享數(shù)據(jù)

D.4 &lt;future&gt;頭文件

<future>頭文件提供處理異步結(jié)果(在其他線程上執(zhí)行額結(jié)果)的工具。

頭文件內(nèi)容

namespace std
{
  enum class future_status {
      ready, timeout, deferred };

  enum class future_errc
  {
    broken_promise,
    future_already_retrieved,
    promise_already_satisfied,
    no_state
  };

  class future_error;

  const error_category& future_category();

  error_code make_error_code(future_errc e);
  error_condition make_error_condition(future_errc e);

  template<typename ResultType>
  class future;

  template<typename ResultType>
  class shared_future;

  template<typename ResultType>
  class promise;

  template<typename FunctionSignature>
  class packaged_task; // no definition provided

  template<typename ResultType,typename ... Args>
  class packaged_task<ResultType (Args...)>;

  enum class launch {
    async, deferred
  };

  template<typename FunctionType,typename ... Args>
  future<result_of<FunctionType(Args...)>::type>
  async(FunctionType&& func,Args&& ... args);

  template<typename FunctionType,typename ... Args>
  future<result_of<FunctionType(Args...)>::type>
  async(std::launch policy,FunctionType&& func,Args&& ... args);
}

D.4.1 std::future類型模板

std::future類型模板是為了等待其他線程上的異步結(jié)果。其和std::promise,std::packaged_task類型模板,還有std::async函數(shù)模板,都是為異步結(jié)果準(zhǔn)備的工具。只有std::future實(shí)例可以在任意時(shí)間引用異步結(jié)果。

std::future實(shí)例是MoveConstructible(移動(dòng)構(gòu)造)和MoveAssignable(移動(dòng)賦值),不過(guò)不能CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。

類型聲明

template<typename ResultType>
class future
{
public:
  future() noexcept;
  future(future&&) noexcept;
  future& operator=(future&&) noexcept;
  ~future();

  future(future const&) = delete;
  future& operator=(future const&) = delete;

  shared_future<ResultType> share();

  bool valid() const noexcept;

  see description get();

  void wait();

  template<typename Rep,typename Period>
  future_status wait_for(
      std::chrono::duration<Rep,Period> const& relative_time);

  template<typename Clock,typename Duration>
  future_status wait_until(
      std::chrono::time_point<Clock,Duration> const& absolute_time);
};

std::future 默認(rèn)構(gòu)造函數(shù)

不使用異步結(jié)果構(gòu)造一個(gè)std::future對(duì)象。

聲明

future() noexcept;

效果
構(gòu)造一個(gè)新的std::future實(shí)例。

后置條件
valid()返回false。

拋出
無(wú)

std::future 移動(dòng)構(gòu)造函數(shù)

使用另外一個(gè)對(duì)象,構(gòu)造一個(gè)std::future對(duì)象,將相關(guān)異步結(jié)果的所有權(quán)轉(zhuǎn)移給新std::future對(duì)象。

聲明

future(future&& other) noexcept;

效果
使用已有對(duì)象構(gòu)造一個(gè)新的std::future對(duì)象。

后置條件
已有對(duì)象中的異步結(jié)果,將于新的對(duì)象相關(guān)聯(lián)。然后,解除已有對(duì)象和異步之間的關(guān)系。this->valid()返回的結(jié)果與之前已有對(duì)象other.valid()返回的結(jié)果相同。在調(diào)用該構(gòu)造函數(shù)后,other.valid()將返回false。

拋出
無(wú)

std::future 移動(dòng)賦值操作

將已有std::future對(duì)象中異步結(jié)果的所有權(quán),轉(zhuǎn)移到另一對(duì)象當(dāng)中。

聲明

future(future&& other) noexcept;

效果
在兩個(gè)std::future實(shí)例中轉(zhuǎn)移異步結(jié)果的狀態(tài)。

后置條件
當(dāng)執(zhí)行完賦值操作后,*this.other就與異步結(jié)果沒(méi)有關(guān)系了。異步狀態(tài)(如果有的話)在釋放后與*this相關(guān),并且在最后一次引用后,銷毀該狀態(tài)。this->valid()返回的結(jié)果與之前已有對(duì)象other.valid()返回的結(jié)果相同。在調(diào)用該構(gòu)造函數(shù)后,other.valid()將返回false。

拋出
無(wú)

std::future 析構(gòu)函數(shù)

銷毀一個(gè)std::future對(duì)象。

聲明

~future();

效果
銷毀*this。如果這是最后一次引用與*this相關(guān)的異步結(jié)果,之后就會(huì)將該異步結(jié)果銷毀。

拋出
無(wú)

std::future::share 成員函數(shù)

構(gòu)造一個(gè)新std::shared_future實(shí)例,并且將*this異步結(jié)果的所有權(quán)轉(zhuǎn)移到新的std::shared_future實(shí)例中。

聲明

shared_future<ResultType> share();

效果
如同 shared_future(std::move(*this))。

后置條件
當(dāng)調(diào)用share()成員函數(shù),與*this相關(guān)的異步結(jié)果將與新構(gòu)造的std::shared_future實(shí)例相關(guān)。this->valid()將返回false。

拋出
無(wú)

std::future::valid 成員函數(shù)

檢查std::future實(shí)例是否與一個(gè)異步結(jié)果相關(guān)聯(lián)。

聲明

bool valid() const noexcept;

返回
當(dāng)與異步結(jié)果相關(guān)時(shí),返回true,否則返回false。

拋出
無(wú)

std::future::wait 成員函數(shù)

如果與*this相關(guān)的狀態(tài)包含延遲函數(shù),將調(diào)用該函數(shù)。否則,會(huì)等待std::future實(shí)例中的異步結(jié)果準(zhǔn)備就緒。

聲明

void wait();

先決條件
this->valid()將會(huì)返回true。

效果
當(dāng)相關(guān)狀態(tài)包含延遲函數(shù),調(diào)用延遲函數(shù),并保存返回的結(jié)果,或?qū)伋龅漠惓14娉蔀楫惒浇Y(jié)果。否則,會(huì)阻塞到*this準(zhǔn)備就緒。

拋出
無(wú)

std::future::wait_for 成員函數(shù)

等待std::future實(shí)例上相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)某個(gè)給定的時(shí)間。

聲明

template<typename Rep,typename Period>
future_status wait_for(
    std::chrono::duration<Rep,Period> const& relative_time);

先決條件
this->valid()將會(huì)返回true。

效果
如果與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),那么就不阻塞立即返回。否則將阻塞實(shí)例,直到與*this相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)給定的relative_time時(shí)長(zhǎng)。

返回
當(dāng)與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),返回std::future_status::deferred;當(dāng)與*this相關(guān)的異步結(jié)果準(zhǔn)備就緒,返回std::future_status::ready;當(dāng)給定時(shí)間超過(guò)relative_time時(shí),返回std::future_status::timeout。

NOTE:線程阻塞的時(shí)間可能超多給定的時(shí)長(zhǎng)。時(shí)長(zhǎng)盡可能由一個(gè)穩(wěn)定的時(shí)鐘決定。

拋出
無(wú)

std::future::wait_until 成員函數(shù)

等待std::future實(shí)例上相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)某個(gè)給定的時(shí)間。

聲明

template<typename Clock,typename Duration>
future_status wait_until(
  std::chrono::time_point<Clock,Duration> const& absolute_time);

先決條件
this->valid()將返回true。

效果
如果與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),那么就不阻塞立即返回。否則將阻塞實(shí)例,直到與*this相關(guān)異步結(jié)果準(zhǔn)備就緒,或Clock::now()返回的時(shí)間大于等于absolute_time。

返回
當(dāng)與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),返回std::future_status::deferred;當(dāng)與*this相關(guān)的異步結(jié)果準(zhǔn)備就緒,返回std::future_status::readyClock::now()返回的時(shí)間大于等于absolute_time,返回std::future_status::timeout。

NOTE:這里不保證調(diào)用線程會(huì)被阻塞多久,只有函數(shù)返回std::future_status::timeout,然后Clock::now()返回的時(shí)間大于等于absolute_time的時(shí)候,線程才會(huì)解除阻塞。

拋出
無(wú)

std::future::get 成員函數(shù)

當(dāng)相關(guān)狀態(tài)包含一個(gè)std::async調(diào)用的延遲函數(shù),調(diào)用該延遲函數(shù),并返回結(jié)果;否則,等待與std::future實(shí)例相關(guān)的異步結(jié)果準(zhǔn)備就緒,之后返回存儲(chǔ)的值或異常。

聲明

void future<void>::get();
R& future<R&>::get();
R future<R>::get();

先決條件
this->valid()將返回true。

效果
如果*this相關(guān)狀態(tài)包含一個(gè)延期函數(shù),那么調(diào)用這個(gè)函數(shù)并返回結(jié)果,或?qū)伋龅漠惓_M(jìn)行傳播。

否則,線程就要被阻塞,直到與*this相關(guān)的異步結(jié)果就緒。當(dāng)結(jié)果存儲(chǔ)了一個(gè)異常,那么就就會(huì)將存儲(chǔ)異常拋出。否則,將會(huì)返回存儲(chǔ)值。

返回
當(dāng)相關(guān)狀態(tài)包含一個(gè)延期函數(shù),那么這個(gè)延期函數(shù)的結(jié)果將被返回。否則,當(dāng)ResultType為void時(shí),就會(huì)按照常規(guī)調(diào)用返回。如果ResultType是R&(R類型的引用),存儲(chǔ)的引用值將會(huì)被返回。否則,存儲(chǔ)的值將會(huì)返回。

拋出
異常由延期函數(shù),或存儲(chǔ)在異步結(jié)果中的異常(如果有的話)拋出。

后置條件

this->valid()==false

D.4.2 std::shared_future類型模板

std::shared_future類型模板是為了等待其他線程上的異步結(jié)果。其和std::promise,std::packaged_task類型模板,還有std::async函數(shù)模板,都是為異步結(jié)果準(zhǔn)備的工具。多個(gè)std::shared_future實(shí)例可以引用同一個(gè)異步結(jié)果。

std::shared_future實(shí)例是CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。你也可以同ResultType的std::future類型對(duì)象,移動(dòng)構(gòu)造一個(gè)std::shared_future類型對(duì)象。

訪問(wèn)給定std::shared_future實(shí)例是非同步的。因此,當(dāng)有多個(gè)線程訪問(wèn)同一個(gè)std::shared_future實(shí)例,且無(wú)任何外圍同步操作時(shí),這樣的訪問(wèn)是不安全的。不過(guò)訪問(wèn)關(guān)聯(lián)狀態(tài)時(shí)是同步的,所以多個(gè)線程訪問(wèn)多個(gè)獨(dú)立的std::shared_future實(shí)例,且沒(méi)有外圍同步操作的時(shí)候,是安全的。

類型定義

template<typename ResultType>
class shared_future
{
public:
  shared_future() noexcept;
  shared_future(future<ResultType>&&) noexcept;

  shared_future(shared_future&&) noexcept;
  shared_future(shared_future const&);
  shared_future& operator=(shared_future const&);
  shared_future& operator=(shared_future&&) noexcept;
  ~shared_future();

  bool valid() const noexcept;

  see description get() const;

  void wait() const;

  template<typename Rep,typename Period>
  future_status wait_for(
     std::chrono::duration<Rep,Period> const& relative_time) const;

  template<typename Clock,typename Duration>
  future_status wait_until(
     std::chrono::time_point<Clock,Duration> const& absolute_time)
    const;
};

std::shared_future 默認(rèn)構(gòu)造函數(shù)

不使用關(guān)聯(lián)異步結(jié)果,構(gòu)造一個(gè)std::shared_future對(duì)象。

聲明

shared_future() noexcept;

效果
構(gòu)造一個(gè)新的std::shared_future實(shí)例。

后置條件
當(dāng)新實(shí)例構(gòu)建完成后,調(diào)用valid()將返回false。

拋出
無(wú)

std::shared_future 移動(dòng)構(gòu)造函數(shù)

以一個(gè)已創(chuàng)建std::shared_future對(duì)象為準(zhǔn),構(gòu)造std::shared_future實(shí)例,并將使用std::shared_future對(duì)象關(guān)聯(lián)的異步結(jié)果的所有權(quán)轉(zhuǎn)移到新的實(shí)例中。

聲明

shared_future(shared_future&& other) noexcept;

效果
構(gòu)造一個(gè)新std::shared_future實(shí)例。

后置條件
將other對(duì)象中關(guān)聯(lián)異步結(jié)果的所有權(quán)轉(zhuǎn)移到新對(duì)象中,這樣other對(duì)象就沒(méi)有與之相關(guān)聯(lián)的異步結(jié)果了。

拋出
無(wú)

std::shared_future 移動(dòng)對(duì)應(yīng)std::future對(duì)象的構(gòu)造函數(shù)

以一個(gè)已創(chuàng)建std::future對(duì)象為準(zhǔn),構(gòu)造std::shared_future實(shí)例,并將使用std::shared_future對(duì)象關(guān)聯(lián)的異步結(jié)果的所有權(quán)轉(zhuǎn)移到新的實(shí)例中。

聲明

shared_future(std::future<ResultType>&& other) noexcept;

效果
構(gòu)造一個(gè)std::shared_future對(duì)象。

后置條件
將other對(duì)象中關(guān)聯(lián)異步結(jié)果的所有權(quán)轉(zhuǎn)移到新對(duì)象中,這樣other對(duì)象就沒(méi)有與之相關(guān)聯(lián)的異步結(jié)果了。

拋出
無(wú)

std::shared_future 拷貝構(gòu)造函數(shù)

以一個(gè)已創(chuàng)建std::future對(duì)象為準(zhǔn),構(gòu)造std::shared_future實(shí)例,并將使用std::shared_future對(duì)象關(guān)聯(lián)的異步結(jié)果(如果有的話)拷貝到新創(chuàng)建對(duì)象當(dāng)中,兩個(gè)對(duì)象共享該異步結(jié)果。

聲明

shared_future(shared_future const& other);

效果
構(gòu)造一個(gè)std::shared_future對(duì)象。

后置條件
將other對(duì)象中關(guān)聯(lián)異步結(jié)果拷貝到新對(duì)象中,與other共享關(guān)聯(lián)的異步結(jié)果。

拋出
無(wú)

std::shared_future 析構(gòu)函數(shù)

銷毀一個(gè)std::shared_future對(duì)象。

聲明

~shared_future();

效果
*this銷毀。如果*this關(guān)聯(lián)的異步結(jié)果與std::promisestd::packaged_task不再有關(guān)聯(lián),那么該函數(shù)將會(huì)切斷std::shared_future實(shí)例與異步結(jié)果的聯(lián)系,并銷毀異步結(jié)果。

拋出
無(wú)

std::shared_future::valid 成員函數(shù)

檢查std::shared_future實(shí)例是否與一個(gè)異步結(jié)果相關(guān)聯(lián)。

聲明

bool valid() const noexcept;

返回
當(dāng)與異步結(jié)果相關(guān)時(shí),返回true,否則返回false。

拋出
無(wú)

std::shared_future::wait 成員函數(shù)

當(dāng)*this關(guān)聯(lián)狀態(tài)包含一個(gè)延期函數(shù),那么調(diào)用這個(gè)函數(shù)。否則,等待直到與std::shared_future實(shí)例相關(guān)的異步結(jié)果就緒為止。

聲明

void wait() const;

先決條件 this->valid()將返回true。

效果
當(dāng)有多個(gè)線程調(diào)用std::shared_future實(shí)例上的get()和wait()時(shí),實(shí)例會(huì)序列化的共享同一關(guān)聯(lián)狀態(tài)。如果關(guān)聯(lián)狀態(tài)包括一個(gè)延期函數(shù),那么第一個(gè)調(diào)用get()或wait()時(shí)就會(huì)調(diào)用延期函數(shù),并且存儲(chǔ)返回值,或?qū)伋霎惓R援惒浇Y(jié)果的方式保存下來(lái)。

拋出
無(wú)

std::shared_future::wait_for 成員函數(shù)

等待std::shared_future實(shí)例上相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)某個(gè)給定的時(shí)間。

聲明

template<typename Rep,typename Period>
future_status wait_for(
    std::chrono::duration<Rep,Period> const& relative_time) const;

先決條件
this->valid()將會(huì)返回true。

效果
如果與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延期函數(shù)(還未執(zhí)行),那么就不阻塞立即返回。否則將阻塞實(shí)例,直到與*this相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)給定的relative_time時(shí)長(zhǎng)。

返回
當(dāng)與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),返回std::future_status::deferred;當(dāng)與*this相關(guān)的異步結(jié)果準(zhǔn)備就緒,返回std::future_status::ready;當(dāng)給定時(shí)間超過(guò)relative_time時(shí),返回std::future_status::timeout。

NOTE:線程阻塞的時(shí)間可能超多給定的時(shí)長(zhǎng)。時(shí)長(zhǎng)盡可能由一個(gè)穩(wěn)定的時(shí)鐘決定。

拋出
無(wú)

std::shared_future::wait_until 成員函數(shù)

等待std::future實(shí)例上相關(guān)異步結(jié)果準(zhǔn)備就緒,或超過(guò)某個(gè)給定的時(shí)間。

聲明

template<typename Clock,typename Duration>
future_status wait_until(
  std::chrono::time_point<Clock,Duration> const& absolute_time) const;

先決條件
this->valid()將返回true。

效果
如果與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),那么就不阻塞立即返回。否則將阻塞實(shí)例,直到與*this相關(guān)異步結(jié)果準(zhǔn)備就緒,或Clock::now()返回的時(shí)間大于等于absolute_time。

返回
當(dāng)與*this相關(guān)的異步結(jié)果包含一個(gè)std::async調(diào)用的延遲函數(shù)(還未執(zhí)行),返回std::future_status::deferred;當(dāng)與*this相關(guān)的異步結(jié)果準(zhǔn)備就緒,返回std::future_status::ready;Clock::now()返回的時(shí)間大于等于absolute_time,返回std::future_status::timeout

NOTE:這里不保證調(diào)用線程會(huì)被阻塞多久,只有函數(shù)返回std::future_status::timeout,然后Clock::now()返回的時(shí)間大于等于absolute_time的時(shí)候,線程才會(huì)解除阻塞。

拋出
無(wú)

std::shared_future::get 成員函數(shù)

當(dāng)相關(guān)狀態(tài)包含一個(gè)std::async調(diào)用的延遲函數(shù),調(diào)用該延遲函數(shù),并返回結(jié)果;否則,等待與std::shared_future實(shí)例相關(guān)的異步結(jié)果準(zhǔn)備就緒,之后返回存儲(chǔ)的值或異常。

聲明

void shared_future<void>::get() const;
R& shared_future<R&>::get() const;
R const& shared_future<R>::get() const;

先決條件
this->valid()將返回true。

效果
當(dāng)有多個(gè)線程調(diào)用std::shared_future實(shí)例上的get()和wait()時(shí),實(shí)例會(huì)序列化的共享同一關(guān)聯(lián)狀態(tài)。如果關(guān)聯(lián)狀態(tài)包括一個(gè)延期函數(shù),那么第一個(gè)調(diào)用get()或wait()時(shí)就會(huì)調(diào)用延期函數(shù),并且存儲(chǔ)返回值,或?qū)伋霎惓R援惒浇Y(jié)果的方式保存下來(lái)。

阻塞會(huì)知道*this關(guān)聯(lián)的異步結(jié)果就緒后解除。當(dāng)異步結(jié)果存儲(chǔ)了一個(gè)一行,那么就會(huì)拋出這個(gè)異常。否則,返回存儲(chǔ)的值。

返回
當(dāng)ResultType為void時(shí),就會(huì)按照常規(guī)調(diào)用返回。如果ResultType是R&(R類型的引用),存儲(chǔ)的引用值將會(huì)被返回。否則,返回存儲(chǔ)值的const引用。

拋出
拋出存儲(chǔ)的異常(如果有的話)。

D.4.3 std::packaged_task類型模板

std::packaged_task類型模板可打包一個(gè)函數(shù)或其他可調(diào)用對(duì)象,所以當(dāng)函數(shù)通過(guò)std::packaged_task實(shí)例被調(diào)用時(shí),結(jié)果將會(huì)作為異步結(jié)果。這個(gè)結(jié)果可以通過(guò)檢索std::future實(shí)例來(lái)查找。

std::packaged_task實(shí)例是可以MoveConstructible(移動(dòng)構(gòu)造)和MoveAssignable(移動(dòng)賦值),不過(guò)不能CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。

類型定義

template<typename FunctionType>
class packaged_task; // undefined

template<typename ResultType,typename... ArgTypes>
class packaged_task<ResultType(ArgTypes...)>
{
public:
  packaged_task() noexcept;
  packaged_task(packaged_task&&) noexcept;
  ~packaged_task();

  packaged_task& operator=(packaged_task&&) noexcept;

  packaged_task(packaged_task const&) = delete;
  packaged_task& operator=(packaged_task const&) = delete;

  void swap(packaged_task&) noexcept;

  template<typename Callable>
  explicit packaged_task(Callable&& func);

  template<typename Callable,typename Allocator>
  packaged_task(std::allocator_arg_t, const Allocator&,Callable&&);

  bool valid() const noexcept;
  std::future<ResultType> get_future();
  void operator()(ArgTypes...);
  void make_ready_at_thread_exit(ArgTypes...);
  void reset();
};

std::packaged_task 默認(rèn)構(gòu)造函數(shù)

構(gòu)造一個(gè)std::packaged_task對(duì)象。

聲明

packaged_task() noexcept;

效果
不使用關(guān)聯(lián)任務(wù)或異步結(jié)果來(lái)構(gòu)造一個(gè)std::packaged_task對(duì)象。

拋出
無(wú)

std::packaged_task 通過(guò)可調(diào)用對(duì)象構(gòu)造

使用關(guān)聯(lián)任務(wù)和異步結(jié)果,構(gòu)造一個(gè)std::packaged_task對(duì)象。

聲明

template<typename Callable>
packaged_task(Callable&& func);

先決條件
表達(dá)式func(args...)必須是合法的,并且在args...中的args-i參數(shù),必須是ArgTypes...中ArgTypes-i類型的一個(gè)值。且返回值必須可轉(zhuǎn)換為ResultType。

效果
使用ResultType類型的關(guān)聯(lián)異步結(jié)果,構(gòu)造一個(gè)std::packaged_task對(duì)象,異步結(jié)果是未就緒的,并且Callable類型相關(guān)的任務(wù)是對(duì)func的一個(gè)拷貝。

拋出
當(dāng)構(gòu)造函數(shù)無(wú)法為異步結(jié)果分配出內(nèi)存時(shí),會(huì)拋出std::bad_alloc類型的異常。其他異常會(huì)在使用Callable類型的拷貝或移動(dòng)構(gòu)造過(guò)程中拋出。

std::packaged_task 通過(guò)有分配器的可調(diào)用對(duì)象構(gòu)造

使用關(guān)聯(lián)任務(wù)和異步結(jié)果,構(gòu)造一個(gè)std::packaged_task對(duì)象。使用以提供的分配器為關(guān)聯(lián)任務(wù)和異步結(jié)果分配內(nèi)存。

聲明

template<typename Allocator,typename Callable>
packaged_task(
    std::allocator_arg_t, Allocator const& alloc,Callable&& func);

先決條件
表達(dá)式func(args...)必須是合法的,并且在args...中的args-i參數(shù),必須是ArgTypes...中ArgTypes-i類型的一個(gè)值。且返回值必須可轉(zhuǎn)換為ResultType。

效果
使用ResultType類型的關(guān)聯(lián)異步結(jié)果,構(gòu)造一個(gè)std::packaged_task對(duì)象,異步結(jié)果是未就緒的,并且Callable類型相關(guān)的任務(wù)是對(duì)func的一個(gè)拷貝。異步結(jié)果和任務(wù)的內(nèi)存通過(guò)內(nèi)存分配器alloc進(jìn)行分配,或進(jìn)行拷貝。

拋出
當(dāng)構(gòu)造函數(shù)無(wú)法為異步結(jié)果分配出內(nèi)存時(shí),會(huì)拋出std::bad_alloc類型的異常。其他異常會(huì)在使用Callable類型的拷貝或移動(dòng)構(gòu)造過(guò)程中拋出。

std::packaged_task 移動(dòng)構(gòu)造函數(shù)

通過(guò)一個(gè)std::packaged_task對(duì)象構(gòu)建另一個(gè),將與已存在的std::packaged_task相關(guān)的異步結(jié)果和任務(wù)的所有權(quán)轉(zhuǎn)移到新構(gòu)建的對(duì)象當(dāng)中。

聲明

packaged_task(packaged_task&& other) noexcept;

效果
構(gòu)建一個(gè)新的std::packaged_task實(shí)例。

后置條件
通過(guò)other構(gòu)建新的std::packaged_task對(duì)象。在新對(duì)象構(gòu)建完成后,other與其之前相關(guān)聯(lián)的異步結(jié)果就沒(méi)有任何關(guān)系了。

拋出
無(wú)

std::packaged_task 移動(dòng)賦值操作

將一個(gè)std::packaged_task對(duì)象相關(guān)的異步結(jié)果的所有權(quán)轉(zhuǎn)移到另外一個(gè)。

聲明

packaged_task& operator=(packaged_task&& other) noexcept;

效果
將other相關(guān)異步結(jié)果和任務(wù)的所有權(quán)轉(zhuǎn)移到*this中,并且切斷異步結(jié)果和任務(wù)與other對(duì)象的關(guān)聯(lián),如同std::packaged_task(other).swap(*this)。

后置條件
與other相關(guān)的異步結(jié)果與任務(wù)移動(dòng)轉(zhuǎn)移,使*this.other無(wú)關(guān)聯(lián)的異步結(jié)果。

返回

*this

拋出
無(wú)

std::packaged_task::swap 成員函數(shù)

將兩個(gè)std::packaged_task對(duì)象所關(guān)聯(lián)的異步結(jié)果的所有權(quán)進(jìn)行交換。

聲明

void swap(packaged_task& other) noexcept;

效果
將other和*this關(guān)聯(lián)的異步結(jié)果與任務(wù)進(jìn)行交換。

后置條件
將與other關(guān)聯(lián)的異步結(jié)果和任務(wù),通過(guò)調(diào)用swap的方式,與*this相交換。

拋出
無(wú)

std::packaged_task 析構(gòu)函數(shù)

銷毀一個(gè)std::packaged_task對(duì)象。

聲明

~packaged_task();

效果
*this銷毀。如果*this有關(guān)聯(lián)的異步結(jié)果,并且結(jié)果不是一個(gè)已存儲(chǔ)的任務(wù)或異常,那么異步結(jié)果狀態(tài)將會(huì)變?yōu)榫途w,伴隨就緒的是一個(gè)std::future_error異常和錯(cuò)誤碼std::future_errc::broken_promise。

拋出
無(wú)

std::packaged_task::get_future 成員函數(shù)

在*this相關(guān)異步結(jié)果中,檢索一個(gè)std::future實(shí)例。

聲明

std::future<ResultType> get_future();

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。

返回
一個(gè)與*this關(guān)聯(lián)異構(gòu)結(jié)果相關(guān)的一個(gè)std::future實(shí)例。

拋出
如果一個(gè)std::future已經(jīng)通過(guò)get_future()獲取了異步結(jié)果,在拋出std::future_error異常時(shí),錯(cuò)誤碼是std::future_errc::future_already_retrieved

std::packaged_task::reset 成員函數(shù)

將一個(gè)std::packaged_task對(duì)實(shí)例與一個(gè)新的異步結(jié)果相關(guān)聯(lián)。

聲明

void reset();

先決條件
*this具有關(guān)聯(lián)的異步任務(wù)。

效果
如同*this=packaged_task(std::move(f)),f是*this中已存儲(chǔ)的關(guān)聯(lián)任務(wù)。

拋出
如果內(nèi)存不足以分配給新的異構(gòu)結(jié)果,那么將會(huì)拋出std::bad_alloc類異常。

std::packaged_task::valid 成員函數(shù)

檢查*this中是都具有關(guān)聯(lián)任務(wù)和異步結(jié)果。

聲明

bool valid() const noexcept;

返回
當(dāng)*this具有相關(guān)任務(wù)和異步結(jié)構(gòu),返回true;否則,返回false。

拋出
無(wú)

std::packaged_task::operator() 函數(shù)調(diào)用操作

調(diào)用一個(gè)std::packaged_task實(shí)例中的相關(guān)任務(wù),并且存儲(chǔ)返回值,或?qū)惓4鎯?chǔ)到異常結(jié)果當(dāng)中。

聲明

void operator()(ArgTypes... args);

先決條件
*this具有相關(guān)任務(wù)。

效果
INVOKE(func,args...)那要調(diào)用相關(guān)的函數(shù)func。如果返回征程,那么將會(huì)存儲(chǔ)到this相關(guān)的異步結(jié)果中。當(dāng)返回結(jié)果是一個(gè)異常,將這個(gè)異常存儲(chǔ)到this相關(guān)的異步結(jié)果中。

后置條件
*this相關(guān)聯(lián)的異步結(jié)果狀態(tài)為就緒,并且存儲(chǔ)了一個(gè)值或異常。所有阻塞線程,在等待到異步結(jié)果的時(shí)候被解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存儲(chǔ)了一個(gè)值或異常,那么將拋出一個(gè)std::future_error異常,錯(cuò)誤碼為std::future_errc::promise_already_satisfied。

同步
std::future<ResultType>::get()std::shared_future<ResultType>::get()的成功調(diào)用,代表同步操作的成功,函數(shù)將會(huì)檢索異步結(jié)果中的值或異常。

std::packaged_task::make_ready_at_thread_exit 成員函數(shù)

調(diào)用一個(gè)std::packaged_task實(shí)例中的相關(guān)任務(wù),并且存儲(chǔ)返回值,或?qū)惓4鎯?chǔ)到異常結(jié)果當(dāng)中,直到線程退出時(shí),將相關(guān)異步結(jié)果的狀態(tài)置為就緒。

聲明

void make_ready_at_thread_exit(ArgTypes... args);

先決條件
*this具有相關(guān)任務(wù)。

效果
INVOKE(func,args...)那要調(diào)用相關(guān)的函數(shù)func。如果返回征程,那么將會(huì)存儲(chǔ)到*this相關(guān)的異步結(jié)果中。當(dāng)返回結(jié)果是一個(gè)異常,將這個(gè)異常存儲(chǔ)到*this相關(guān)的異步結(jié)果中。當(dāng)當(dāng)前線程退出的時(shí)候,可調(diào)配相關(guān)異步狀態(tài)為就緒。

后置條件
*this的異步結(jié)果中已經(jīng)存儲(chǔ)了一個(gè)值或一個(gè)異常,不過(guò)在當(dāng)前線程退出的時(shí)候,這個(gè)結(jié)果都是非就緒的。當(dāng)當(dāng)前線程退出時(shí),阻塞等待異步結(jié)果的線程將會(huì)被解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存儲(chǔ)了一個(gè)值或異常,那么將拋出一個(gè)std::future_error異常,錯(cuò)誤碼為std::future_errc::promise_already_satisfied。當(dāng)無(wú)關(guān)聯(lián)異步狀態(tài)時(shí),拋出std::future_error異常,錯(cuò)誤碼為std::future_errc::no_state。

同步
std::future<ResultType>::get()std::shared_future<ResultType>::get()在線程上的成功調(diào)用,代表同步操作的成功,函數(shù)將會(huì)檢索異步結(jié)果中的值或異常。

D.4.4 std::promise類型模板

std::promise類型模板提供設(shè)置異步結(jié)果的方法,這樣其他線程就可以通過(guò)std::future實(shí)例來(lái)索引該結(jié)果。

ResultType模板參數(shù),該類型可以存儲(chǔ)異步結(jié)果。

std::promise實(shí)例中的異步結(jié)果與某個(gè)srd::future實(shí)例相關(guān)聯(lián),并且可以通過(guò)調(diào)用get_future()成員函數(shù)來(lái)獲取這個(gè)srd::future實(shí)例。ResultType類型的異步結(jié)果,可以通過(guò)set_value()成員函數(shù)對(duì)存儲(chǔ)值進(jìn)行設(shè)置,或者使用set_exception()將對(duì)應(yīng)異常設(shè)置進(jìn)異步結(jié)果中。

std::promise實(shí)例是可以MoveConstructible(移動(dòng)構(gòu)造)和MoveAssignable(移動(dòng)賦值),但是不能CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。

類型定義

template<typename ResultType>
class promise
{
public:
  promise();
  promise(promise&&) noexcept;
  ~promise();
  promise& operator=(promise&&) noexcept;

  template<typename Allocator>
  promise(std::allocator_arg_t, Allocator const&);

  promise(promise const&) = delete;
  promise& operator=(promise const&) = delete;

  void swap(promise& ) noexcept;

  std::future<ResultType> get_future();

  void set_value(see description);
  void set_exception(std::exception_ptr p);
};

std::promise 默認(rèn)構(gòu)造函數(shù)

構(gòu)造一個(gè)std::promise對(duì)象。

聲明

promise();

效果
使用ResultType類型的相關(guān)異步結(jié)果來(lái)構(gòu)造std::promise實(shí)例,不過(guò)異步結(jié)果并未就緒。

拋出
當(dāng)沒(méi)有足夠內(nèi)存為異步結(jié)果進(jìn)行分配,那么將拋出std::bad_alloc型異常。

std::promise 帶分配器的構(gòu)造函數(shù)

構(gòu)造一個(gè)std::promise對(duì)象,使用提供的分配器來(lái)為相關(guān)異步結(jié)果分配內(nèi)存。

聲明

template<typename Allocator>
promise(std::allocator_arg_t, Allocator const& alloc);

效果
使用ResultType類型的相關(guān)異步結(jié)果來(lái)構(gòu)造std::promise實(shí)例,不過(guò)異步結(jié)果并未就緒。異步結(jié)果的內(nèi)存由alloc分配器來(lái)分配。

拋出
當(dāng)分配器為異步結(jié)果分配內(nèi)存時(shí),如有拋出異常,就為該函數(shù)拋出的異常。

std::promise 移動(dòng)構(gòu)造函數(shù)

通過(guò)另一個(gè)已存在對(duì)象,構(gòu)造一個(gè)std::promise對(duì)象。將已存在對(duì)象中的相關(guān)異步結(jié)果的所有權(quán)轉(zhuǎn)移到新創(chuàng)建的std::promise對(duì)象當(dāng)中。

聲明

promise(promise&& other) noexcept;

效果
構(gòu)造一個(gè)std::promise實(shí)例。

后置條件
當(dāng)使用other來(lái)構(gòu)造一個(gè)新的實(shí)例,那么other中相關(guān)異構(gòu)結(jié)果的所有權(quán)將轉(zhuǎn)移到新創(chuàng)建的對(duì)象上。之后,other將無(wú)關(guān)聯(lián)異步結(jié)果。

拋出
無(wú)

std::promise 移動(dòng)賦值操作符

在兩個(gè)std::promise實(shí)例中轉(zhuǎn)移異步結(jié)果的所有權(quán)。

聲明

promise& operator=(promise&& other) noexcept;

效果
在other和*this之間進(jìn)行異步結(jié)果所有權(quán)的轉(zhuǎn)移。當(dāng)*this已經(jīng)有關(guān)聯(lián)的異步結(jié)果,那么該異步結(jié)果的狀態(tài)將會(huì)為就緒態(tài),且伴隨一個(gè)std::future_error類型異常,錯(cuò)誤碼為std::future_errc::broken_promise

后置條件
將other中關(guān)聯(lián)的異步結(jié)果轉(zhuǎn)移到*this當(dāng)中。other中將無(wú)關(guān)聯(lián)異步結(jié)果。

返回

*this

拋出
無(wú)

std::promise::swap 成員函數(shù)

將兩個(gè)std::promise實(shí)例中的關(guān)聯(lián)異步結(jié)果進(jìn)行交換。

聲明

void swap(promise& other);

效果
交換other和*this當(dāng)中的關(guān)聯(lián)異步結(jié)果。

后置條件
當(dāng)swap使用other時(shí),other中的異步結(jié)果就會(huì)與*this中關(guān)聯(lián)異步結(jié)果相交換。二者返回來(lái)亦然。

拋出
無(wú)

std::promise 析構(gòu)函數(shù)

銷毀std::promise對(duì)象。

聲明

~promise();

效果
銷毀*this。當(dāng)*this具有關(guān)聯(lián)的異步結(jié)果,并且結(jié)果中沒(méi)有存儲(chǔ)值或異常,那么結(jié)果將會(huì)置為就緒,伴隨一個(gè)std::future_error異常,錯(cuò)誤碼為std::future_errc::broken_promise。

拋出
無(wú)

std::promise::get_future 成員函數(shù)

通過(guò)*this關(guān)聯(lián)的異步結(jié)果,檢索出所要的std::future實(shí)例。

聲明

std::future<ResultType> get_future();

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。

返回
與*this關(guān)聯(lián)異步結(jié)果關(guān)聯(lián)的std::future實(shí)例。

拋出
當(dāng)std::future已經(jīng)通過(guò)get_future()獲取過(guò)了,將會(huì)拋出一個(gè)std::future_error類型異常,伴隨的錯(cuò)誤碼為std::future_errc::future_already_retrieved

std::promise::set_value 成員函數(shù)

存儲(chǔ)一個(gè)值到與*this關(guān)聯(lián)的異步結(jié)果中。

聲明

void promise<void>::set_value();
void promise<R&>::set_value(R& r);
void promise<R>::set_value(R const& r);
void promise<R>::set_value(R&& r);

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。

效果
當(dāng)ResultType不是void型,就存儲(chǔ)r到*this相關(guān)的異步結(jié)果當(dāng)中。

后置條件
*this相關(guān)的異步結(jié)果的狀態(tài)為就緒,且將值存入。任意等待異步結(jié)果的阻塞線程將解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存有一個(gè)值或一個(gè)異常,那么將拋出std::future_error型異常,伴隨錯(cuò)誤碼為std::future_errc::promise_already_satisfied。r的拷貝構(gòu)造或移動(dòng)構(gòu)造拋出的異常,即為本函數(shù)拋出的異常。

同步
并發(fā)調(diào)用set_value()和set_exception()的線程將被序列化。要想成功的調(diào)用set_exception(),需要在之前調(diào)用std::future<Result-Type>::get()std::shared_future<ResultType>::get(),這兩個(gè)函數(shù)將會(huì)查找已存儲(chǔ)的異常。

std::promise::set_value_at_thread_exit 成員函數(shù)

存儲(chǔ)一個(gè)值到與*this關(guān)聯(lián)的異步結(jié)果中,到線程退出時(shí),異步結(jié)果的狀態(tài)會(huì)被設(shè)置為就緒。

聲明

void promise<void>::set_value_at_thread_exit();
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<R>::set_value_at_thread_exit(R const& r);
void promise<R>::set_value_at_thread_exit(R&& r);

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。

效果
當(dāng)ResultType不是void型,就存儲(chǔ)r到*this相關(guān)的異步結(jié)果當(dāng)中。標(biāo)記異步結(jié)果為“已存儲(chǔ)值”。當(dāng)前線程退出時(shí),會(huì)安排相關(guān)異步結(jié)果的狀態(tài)為就緒。

后置條件
將值存入*this相關(guān)的異步結(jié)果,且直到當(dāng)前線程退出時(shí),異步結(jié)果狀態(tài)被置為就緒。任何等待異步結(jié)果的阻塞線程將解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存有一個(gè)值或一個(gè)異常,那么將拋出std::future_error型異常,伴隨錯(cuò)誤碼為std::future_errc::promise_already_satisfied。r的拷貝構(gòu)造或移動(dòng)構(gòu)造拋出的異常,即為本函數(shù)拋出的異常。

同步
并發(fā)調(diào)用set_value(), set_value_at_thread_exit(), set_exception()和set_exception_at_thread_exit()的線程將被序列化。要想成功的調(diào)用set_exception(),需要在之前調(diào)用std::future<Result-Type>::get()std::shared_future<ResultType>::get(),這兩個(gè)函數(shù)將會(huì)查找已存儲(chǔ)的異常。

std::promise::set_exception 成員函數(shù)

存儲(chǔ)一個(gè)異常到與*this關(guān)聯(lián)的異步結(jié)果中。

聲明

void set_exception(std::exception_ptr e);

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。(bool)e為true。

效果
將e存儲(chǔ)到*this相關(guān)的異步結(jié)果中。

后置條件
在存儲(chǔ)異常后,*this相關(guān)的異步結(jié)果的狀態(tài)將置為繼續(xù)。任何等待異步結(jié)果的阻塞線程將解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存有一個(gè)值或一個(gè)異常,那么將拋出std::future_error型異常,伴隨錯(cuò)誤碼為std::future_errc::promise_already_satisfied

同步
并發(fā)調(diào)用set_value()和set_exception()的線程將被序列化。要想成功的調(diào)用set_exception(),需要在之前調(diào)用std::future<Result-Type>::get()std::shared_future<ResultType>::get(),這兩個(gè)函數(shù)將會(huì)查找已存儲(chǔ)的異常。

std::promise::set_exception_at_thread_exit 成員函數(shù)

存儲(chǔ)一個(gè)異常到與*this關(guān)聯(lián)的異步結(jié)果中,知道當(dāng)前線程退出,異步結(jié)果被置為就緒。

聲明

void set_exception_at_thread_exit(std::exception_ptr e);

先決條件
*this具有關(guān)聯(lián)異步結(jié)果。(bool)e為true。

效果
將e存儲(chǔ)到*this相關(guān)的異步結(jié)果中。標(biāo)記異步結(jié)果為“已存儲(chǔ)值”。當(dāng)前線程退出時(shí),會(huì)安排相關(guān)異步結(jié)果的狀態(tài)為就緒。

后置條件
將值存入*this相關(guān)的異步結(jié)果,且直到當(dāng)前線程退出時(shí),異步結(jié)果狀態(tài)被置為就緒。任何等待異步結(jié)果的阻塞線程將解除阻塞。

拋出
當(dāng)異步結(jié)果已經(jīng)存有一個(gè)值或一個(gè)異常,那么將拋出std::future_error型異常,伴隨錯(cuò)誤碼為std::future_errc::promise_already_satisfied

同步
并發(fā)調(diào)用set_value(), set_value_at_thread_exit(), set_exception()和set_exception_at_thread_exit()的線程將被序列化。要想成功的調(diào)用set_exception(),需要在之前調(diào)用std::future<Result-Type>::get()std::shared_future<ResultType>::get(),這兩個(gè)函數(shù)將會(huì)查找已存儲(chǔ)的異常。

D.4.5 std::async函數(shù)模板

std::async能夠簡(jiǎn)單的使用可用的硬件并行來(lái)運(yùn)行自身包含的異步任務(wù)。當(dāng)調(diào)用std::async返回一個(gè)包含任務(wù)結(jié)果的std::future對(duì)象。根據(jù)投放策略,任務(wù)在其所在線程上是異步運(yùn)行的,當(dāng)有線程調(diào)用了這個(gè)future對(duì)象的wait()和get()成員函數(shù),則該任務(wù)會(huì)同步運(yùn)行。

聲明

enum class launch
{
  async,deferred
};

template<typename Callable,typename ... Args>
future<result_of<Callable(Args...)>::type>
async(Callable&& func,Args&& ... args);

template<typename Callable,typename ... Args>
future<result_of<Callable(Args...)>::type>
async(launch policy,Callable&& func,Args&& ... args);

先決條件
表達(dá)式INVOKE(func,args)能都為func提供合法的值和args。Callable和Args的所有成員都可MoveConstructible(可移動(dòng)構(gòu)造)。

效果
在內(nèi)部存儲(chǔ)中拷貝構(gòu)造funcarg...(分別使用fff和xyz...進(jìn)行表示)。

當(dāng)policy是std::launch::async,運(yùn)行INVOKE(fff,xyz...)在所在線程上。當(dāng)這個(gè)線程完成時(shí),返回的std::future狀態(tài)將會(huì)為就緒態(tài),并且之后會(huì)返回對(duì)應(yīng)的值或異常(由調(diào)用函數(shù)拋出)。析構(gòu)函數(shù)會(huì)等待返回的std::future相關(guān)異步狀態(tài)為就緒時(shí),才解除阻塞。

當(dāng)policy是std::launch::deferred,fff和xyx...都會(huì)作為延期函數(shù)調(diào)用,存儲(chǔ)在返回的std::future。首次調(diào)用future的wait()或get()成員函數(shù),將會(huì)共享相關(guān)狀態(tài),之后執(zhí)行的INVOKE(fff,xyz...)與調(diào)用wait()或get()函數(shù)的線程同步執(zhí)行。

執(zhí)行INVOKE(fff,xyz...)后,在調(diào)用std::future的成員函數(shù)get()時(shí),就會(huì)有值返回或有異常拋出。

當(dāng)policy是std::launch::async | std::launch::deferred或是policy參數(shù)被省略,其行為如同已指定的std::launch::asyncstd::launch::deferred。具體實(shí)現(xiàn)將會(huì)通過(guò)逐漸遞增的方式(call-by-call basis)最大化利用可用的硬件并行,并避免超限分配的問(wèn)題。

在所有的情況下,std::async調(diào)用都會(huì)直接返回。

同步
完成函數(shù)調(diào)用的先行條件是,需要通過(guò)調(diào)用std::futurestd::shared_future實(shí)例的wait(),get(),wait_for()或wait_until(),返回的對(duì)象與std::async返回的std::future對(duì)象關(guān)聯(lián)的狀態(tài)相同才算成功。就std::launch::async這個(gè)policy來(lái)說(shuō),在完成線程上的函數(shù)前,也需要先行對(duì)上面的函數(shù)調(diào)用后,成功的返回才行。

拋出
當(dāng)內(nèi)部存儲(chǔ)無(wú)法分配所需的空間,將拋出std::bad_alloc類型異常;否則,當(dāng)效果沒(méi)有達(dá)到,或任何異常在構(gòu)造fff和xyz...發(fā)生時(shí),拋出std::fu