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

D.2 &lt;condition_variable&gt;頭文件

<condition_variable>頭文件提供了條件變量的定義。其作為基本同步機制,允許被阻塞的線程在某些條件達成或超時時,解除阻塞繼續(xù)執(zhí)行。

頭文件內(nèi)容

namespace std
{
  enum class cv_status { timeout, no_timeout };

  class condition_variable;
  class condition_variable_any;
}

D.2.1 std::condition_variable類

std::condition_variable允許阻塞一個線程,直到條件達成。

std::condition_variable實例不支持CopyAssignable(拷貝賦值), CopyConstructible(拷貝構(gòu)造), MoveAssignable(移動賦值)和 MoveConstructible(移動構(gòu)造)。

類型定義

class condition_variable
{
public:
  condition_variable();
  ~condition_variable();

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

  void notify_one() noexcept;
  void notify_all() noexcept;

  void wait(std::unique_lock<std::mutex>& lock);

  template <typename Predicate>
  void wait(std::unique_lock<std::mutex>& lock,Predicate pred);

  template <typename Clock, typename Duration>
  cv_status wait_until(
       std::unique_lock<std::mutex>& lock,
       const std::chrono::time_point<Clock, Duration>& absolute_time);

  template <typename Clock, typename Duration, typename Predicate>
  bool wait_until(
       std::unique_lock<std::mutex>& lock,
       const std::chrono::time_point<Clock, Duration>& absolute_time,
       Predicate pred);

  template <typename Rep, typename Period>
  cv_status wait_for(
       std::unique_lock<std::mutex>& lock,
       const std::chrono::duration<Rep, Period>& relative_time);

  template <typename Rep, typename Period, typename Predicate>
  bool wait_for(
       std::unique_lock<std::mutex>& lock,
       const std::chrono::duration<Rep, Period>& relative_time,
       Predicate pred);
};

void notify_all_at_thread_exit(condition_variable&,unique_lock<mutex>);

std::condition_variable 默認構(gòu)造函數(shù)

構(gòu)造一個std::condition_variable對象。

聲明

condition_variable();

效果
構(gòu)造一個新的std::condition_variable實例。

拋出
當(dāng)條件變量無法夠早的時候,將會拋出一個std::system_error異常。

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

銷毀一個std::condition_variable對象。

聲明

~condition_variable();

先決條件
之前沒有使用*this總的wait(),wait_for()或wait_until()阻塞過線程。

效果
銷毀*this。

拋出

std::condition_variable::notify_one 成員函數(shù)

喚醒一個等待當(dāng)前std::condition_variable實例的線程。

聲明

void notify_one() noexcept;

效果
喚醒一個等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果。

拋出
當(dāng)效果沒有達成,就會拋出std::system_error異常。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable::notify_all 成員函數(shù)

喚醒所有等待當(dāng)前std::condition_variable實例的線程。

聲明

void notify_all() noexcept;

效果
喚醒所有等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果。

拋出
當(dāng)效果沒有達成,就會拋出std::system_error異常

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

通過std::condition_variable的notify_one()、notify_all()或偽喚醒結(jié)束等待。

等待

void wait(std::unique_lock<std::mutex>& lock);

先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
自動解鎖lock對象,對于線程等待線程,當(dāng)其他線程調(diào)用notify_one()或notify_all()時被喚醒,亦或該線程處于偽喚醒狀態(tài)。在wait()返回前,lock對象將會再次上鎖。

拋出
當(dāng)效果沒有達成的時候,將會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait()階段被解鎖,那么當(dāng)wait()退出的時候lock會再次上鎖,即使函數(shù)是通過異常的方式退出。

NOTE:偽喚醒意味著一個線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時,還處以蘇醒狀態(tài)。因此,建議對wait()進行重載,在可能的情況下使用一個謂詞。否則,建議wait()使用循環(huán)檢查與條件變量相關(guān)的謂詞。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable::wait 需要一個謂詞的成員函數(shù)重載

等待std::condition_variable上的notify_one()或notify_all()被調(diào)用,或謂詞為true的情況,來喚醒線程。

聲明

template<typename Predicate>
void wait(std::unique_lock<std::mutex>& lock,Predicate pred);

先決條件
pred()謂詞必須是合法的,并且需要返回一個值,這個值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
正如

while(!pred())
{
  wait(lock);
}

拋出
pred中可以拋出任意異常,或者當(dāng)效果沒有達到的時候,拋出std::system_error異常。

NOTE:潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后,返回true。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、超時或線程偽喚醒時,結(jié)束等待。

聲明

template<typename Rep,typename Period>
cv_status wait_for(
    std::unique_lock<std::mutex>& lock,
    std::chrono::duration<Rep,Period> const& relative_time);

先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù)時,或超出了relative_time的時間,亦或是線程被偽喚醒,則將lock對象自動解鎖,并將阻塞線程喚醒。當(dāng)wait_for()調(diào)用返回前,lock對象會再次上鎖。

返回
線程被notify_one()、notify_all()或偽喚醒喚醒時,會返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。

拋出
當(dāng)效果沒有達成的時候,會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對象會在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。

NOTE:偽喚醒意味著,一個線程在調(diào)用wait_for()的時候,即使沒有其他線程調(diào)用notify_one()和notify_all()函數(shù),也處于蘇醒狀態(tài)。因此,這里建議重載wait_for()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_for()使用循環(huán)的方式對與謂詞相關(guān)的條件變量進行檢查。在這樣做的時候還需要小心,以確保超時部分依舊有效;wait_until()可能適合更多的情況。這樣的話,線程阻塞的時間就要比指定的時間長了。在有這樣可能性的地方,流逝的時間是由穩(wěn)定時鐘決定。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable::wait_for 需要一個謂詞的成員函數(shù)重載

std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、超時或線程偽喚醒時,結(jié)束等待。

聲明

template<typename Rep,typename Period,typename Predicate>
bool wait_for(
    std::unique_lock<std::mutex>& lock,
    std::chrono::duration<Rep,Period> const& relative_time,
    Predicate pred);

先決條件
pred()謂詞必須是合法的,并且需要返回一個值,這個值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
等價于

internal_clock::time_point end=internal_clock::now()+relative_time;
while(!pred())
{
  std::chrono::duration<Rep,Period> remaining_time=
      end-internal_clock::now();
  if(wait_for(lock,remaining_time)==std::cv_status::timeout)
      return pred();
}
return true;

返回
當(dāng)pred()為true,則返回true;當(dāng)超過relative_time并且pred()返回false時,返回false。

NOTE:潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后返回true,或在指定時間relative_time內(nèi)完成。線程阻塞的時間就要比指定的時間長了。在有這樣可能性的地方,流逝的時間是由穩(wěn)定時鐘決定。

拋出
當(dāng)效果沒有達成時,會拋出std::system_error異?;蛘哂蓀red拋出任意異常。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、指定時間內(nèi)達成條件或線程偽喚醒時,結(jié)束等待。

聲明

template<typename Clock,typename Duration>
cv_status wait_until(
    std::unique_lock<std::mutex>& lock,
    std::chrono::time_point<Clock,Duration> const& absolute_time);

先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù),或Clock::now()返回一個大于或等于absolute_time的時間,亦或線程偽喚醒,lock都將自動解鎖,并且喚醒阻塞的線程。在wait_until()返回之前l(fā)ock對象會再次上鎖。

返回
線程被notify_one()、notify_all()或偽喚醒喚醒時,會返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。

拋出
當(dāng)效果沒有達成的時候,會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對象會在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。

NOTE:偽喚醒意味著一個線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時,還處以蘇醒狀態(tài)。因此,這里建議重載wait_until()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_until()使用循環(huán)的方式對與謂詞相關(guān)的條件變量進行檢查。這里不保證線程會被阻塞多長時間,只有當(dāng)函數(shù)返回false后(Clock::now()的返回值大于或等于absolute_time),線程才能解除阻塞。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable::wait_until 需要一個謂詞的成員函數(shù)重載

std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、謂詞返回true或指定時間內(nèi)達到條件,結(jié)束等待。

聲明

template<typename Clock,typename Duration,typename Predicate>
bool wait_until(
    std::unique_lock<std::mutex>& lock,
    std::chrono::time_point<Clock,Duration> const& absolute_time,
    Predicate pred);

先決條件
pred()必須是合法的,并且其返回值能轉(zhuǎn)換為bool值。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
等價于

while(!pred())
{
  if(wait_until(lock,absolute_time)==std::cv_status::timeout)
    return pred();
}
return true;

返回
當(dāng)調(diào)用pred()返回true時,返回true;當(dāng)Clock::now()的時間大于或等于指定的時間absolute_time,并且pred()返回false時,返回false。

NOTE:潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后返回true,或Clock::now()返回的時間大于或等于absolute_time。這里不保證調(diào)用線程將被阻塞的時長,只有當(dāng)函數(shù)返回false后(Clock::now()返回一個等于或大于absolute_time的值),線程接觸阻塞。

拋出
當(dāng)效果沒有達成時,會拋出std::system_error異?;蛘哂蓀red拋出任意異常。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::notify_all_at_thread_exit 非成員函數(shù)

當(dāng)當(dāng)前調(diào)用函數(shù)的線程退出時,等待std::condition_variable的所有線程將會被喚醒。

聲明

void notify_all_at_thread_exit(
  condition_variable& cv,unique_lock<mutex> lk);

先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lk.owns_lock()必須為true。lk.mutex()需要返回的值要與并發(fā)等待線程相關(guān)的任意cv中鎖對象提供的wait(),wait_for()或wait_until()相同。

效果
將lk的所有權(quán)轉(zhuǎn)移到內(nèi)部存儲中,并且當(dāng)有線程退出時,安排被提醒的cv類。這里的提醒等價于

lk.unlock();
cv.notify_all();

拋出
當(dāng)效果沒有達成時,拋出std::system_error異常。

NOTE:在線程退出前,掌握著鎖的所有權(quán),所以這里要避免死鎖發(fā)生。這里建議調(diào)用該函數(shù)的線程應(yīng)該盡快退出,并且在該線程可以執(zhí)行一些阻塞的操作。用戶必須保證等地線程不會錯誤的將喚醒線程當(dāng)做已退出的線程,特別是偽喚醒??梢酝ㄟ^等待線程上的謂詞測試來實現(xiàn)這一功能,在互斥量保護的情況下,只有謂詞返回true時線程才能被喚醒,并且在調(diào)用notify_all_at_thread_exit(std::condition_variable_any類中函數(shù))前是不會釋放鎖。

D.2.2 std::condition_variable_any類

std::condition_variable_any類允許線程等待某一條件為true的時候繼續(xù)運行。不過std::condition_variable只能和std::unique_lock<std::mutex>一起使用,std::condition_variable_any可以和任意可上鎖(Lockable)類型一起使用。

std::condition_variable_any實例不能進行拷貝賦值(CopyAssignable)、拷貝構(gòu)造(CopyConstructible)、移動賦值(MoveAssignable)或移動構(gòu)造(MoveConstructible)。

類型定義

class condition_variable_any
{
public:
  condition_variable_any();
  ~condition_variable_any();

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

  void notify_one() noexcept;
  void notify_all() noexcept;

  template<typename Lockable>
  void wait(Lockable& lock);

  template <typename Lockable, typename Predicate>
  void wait(Lockable& lock, Predicate pred);

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

  template <
      typename Lockable, typename Clock,
      typename Duration, typename Predicate>
  bool wait_until(
      Lockable& lock,
      const std::chrono::time_point<Clock, Duration>& absolute_time,
      Predicate pred);

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

  template <
      typename Lockable, typename Rep,
      typename Period, typename Predicate>
  bool wait_for(
      Lockable& lock,
      const std::chrono::duration<Rep, Period>& relative_time,
      Predicate pred);
};

std::condition_variable_any 默認構(gòu)造函數(shù)

構(gòu)造一個std::condition_variable_any對象。

聲明

condition_variable_any();

效果
構(gòu)造一個新的std::condition_variable_any實例。

拋出
當(dāng)條件變量構(gòu)造成功,將拋出std::system_error異常。

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

銷毀std::condition_variable_any對象。

聲明

~condition_variable_any();

先決條件
之前沒有使用*this總的wait(),wait_for()或wait_until()阻塞過線程。

效果
銷毀*this。

拋出

std::condition_variable_any::notify_one 成員函數(shù)

std::condition_variable_any喚醒一個等待該條件變量的線程。

聲明

void notify_all() noexcept;

效果
喚醒一個等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果

拋出
當(dāng)效果沒有達成,就會拋出std::system_error異常。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable_any::notify_all 成員函數(shù)

喚醒所有等待當(dāng)前std::condition_variable_any實例的線程。

聲明

void notify_all() noexcept;

效果
喚醒所有等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果

拋出
當(dāng)效果沒有達成,就會拋出std::system_error異常。

同步
std::condition_variable實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

通過std::condition_variable_any的notify_one()、notify_all()或偽喚醒結(jié)束等待。

聲明

template<typename Lockable>
void wait(Lockable& lock);

先決條件
Lockable類型需要能夠上鎖,lock對象擁有一個鎖。

效果
自動解鎖lock對象,對于線程等待線程,當(dāng)其他線程調(diào)用notify_one()或notify_all()時被喚醒,亦或該線程處于偽喚醒狀態(tài)。在wait()返回前,lock對象將會再次上鎖。

拋出
當(dāng)效果沒有達成的時候,將會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait()階段被解鎖,那么當(dāng)wait()退出的時候lock會再次上鎖,即使函數(shù)是通過異常的方式退出。

NOTE:偽喚醒意味著一個線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時,還處以蘇醒狀態(tài)。因此,建議對wait()進行重載,在可能的情況下使用一個謂詞。否則,建議wait()使用循環(huán)檢查與條件變量相關(guān)的謂詞。

同步
std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable_any::wait 需要一個謂詞的成員函數(shù)重載

等待std::condition_variable_any上的notify_one()或notify_all()被調(diào)用,或謂詞為true的情況,來喚醒線程。

聲明

template<typename Lockable,typename Predicate>
void wait(Lockable& lock,Predicate pred);

先決條件
pred()謂詞必須是合法的,并且需要返回一個值,這個值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
正如

while(!pred())
{
wait(lock);
}

拋出
pred中可以拋出任意異常,或者當(dāng)效果沒有達到的時候,拋出std::system_error異常。

NOTE:潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后,返回true。

同步
std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、超時或線程偽喚醒時,結(jié)束等待。

聲明

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

先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù)時,或超出了relative_time的時間,亦或是線程被偽喚醒,則將lock對象自動解鎖,并將阻塞線程喚醒。當(dāng)wait_for()調(diào)用返回前,lock對象會再次上鎖。

返回
線程被notify_one()、notify_all()或偽喚醒喚醒時,會返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。

拋出
當(dāng)效果沒有達成的時候,會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對象會在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。

NOTE:偽喚醒意味著,一個線程在調(diào)用wait_for()的時候,即使沒有其他線程調(diào)用notify_one()和notify_all()函數(shù),也處于蘇醒狀態(tài)。因此,這里建議重載wait_for()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_for()使用循環(huán)的方式對與謂詞相關(guān)的條件變量進行檢查。在這樣做的時候還需要小心,以確保超時部分依舊有效;wait_until()可能適合更多的情況。這樣的話,線程阻塞的時間就要比指定的時間長了。在有這樣可能性的地方,流逝的時間是由穩(wěn)定時鐘決定。

同步
std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable_any::wait_for 需要一個謂詞的成員函數(shù)重載

std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、超時或線程偽喚醒時,結(jié)束等待。

聲明

template<typename Lockable,typename Rep,
    typename Period, typename Predicate>
bool wait_for(
    Lockable& lock,
    std::chrono::duration<Rep,Period> const& relative_time,
    Predicate pred);

先決條件
pred()謂詞必須是合法的,并且需要返回一個值,這個值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
正如

internal_clock::time_point end=internal_clock::now()+relative_time;
while(!pred())
{
  std::chrono::duration<Rep,Period> remaining_time=
      end-internal_clock::now();
  if(wait_for(lock,remaining_time)==std::cv_status::timeout)
      return pred();
}
return true;

返回
當(dāng)pred()為true,則返回true;當(dāng)超過relative_time并且pred()返回false時,返回false。

NOTE: 潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后返回true,或在指定時間relative_time內(nèi)完成。線程阻塞的時間就要比指定的時間長了。在有這樣可能性的地方,流逝的時間是由穩(wěn)定時鐘決定。

拋出
當(dāng)效果沒有達成時,會拋出std::system_error異?;蛘哂蓀red拋出任意異常。

同步
std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

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

std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、指定時間內(nèi)達成條件或線程偽喚醒時,結(jié)束等待

聲明

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

先決條件
Lockable類型需要能夠上鎖,lock對象擁有一個鎖。

效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù),或Clock::now()返回一個大于或等于absolute_time的時間,亦或線程偽喚醒,lock都將自動解鎖,并且喚醒阻塞的線程。在wait_until()返回之前l(fā)ock對象會再次上鎖。

返回
線程被notify_one()、notify_all()或偽喚醒喚醒時,會返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。

拋出
當(dāng)效果沒有達成的時候,會拋出std::system_error異常。當(dāng)lock對象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對象會在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。

NOTE:偽喚醒意味著一個線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時,還處以蘇醒狀態(tài)。因此,這里建議重載wait_until()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_until()使用循環(huán)的方式對與謂詞相關(guān)的條件變量進行檢查。這里不保證線程會被阻塞多長時間,只有當(dāng)函數(shù)返回false后(Clock::now()的返回值大于或等于absolute_time),線程才能解除阻塞。

同步 std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。

std::condition_variable_any::wait_unti 需要一個謂詞的成員函數(shù)重載

std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、謂詞返回true或指定時間內(nèi)達到條件,結(jié)束等待。

聲明

template<typename Lockable,typename Clock,
    typename Duration, typename Predicate>
bool wait_until(
    Lockable& lock,
    std::chrono::time_point<Clock,Duration> const& absolute_time,
    Predicate pred);

先決條件
pred()必須是合法的,并且其返回值能轉(zhuǎn)換為bool值。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。

效果
等價于

while(!pred())
{
  if(wait_until(lock,absolute_time)==std::cv_status::timeout)
    return pred();
}
return true;

返回
當(dāng)調(diào)用pred()返回true時,返回true;當(dāng)Clock::now()的時間大于或等于指定的時間absolute_time,并且pred()返回false時,返回false。

NOTE:潛在的偽喚醒意味著不會指定pred調(diào)用的次數(shù)。通過lock進行上鎖,pred經(jīng)常會被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個值,在(bool)pred()評估后返回true,或Clock::now()返回的時間大于或等于absolute_time。這里不保證調(diào)用線程將被阻塞的時長,只有當(dāng)函數(shù)返回false后(Clock::now()返回一個等于或大于absolute_time的值),線程接觸阻塞。

拋出
當(dāng)效果沒有達成時,會拋出std::system_error異?;蛘哂蓀red拋出任意異常。

同步
std::condition_variable_any實例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。