鍍金池/ 教程/ C/ D.5 <mutex>頭文件
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.5 &lt;mutex&gt;頭文件

<mutex>頭文件提供互斥工具:互斥類型,鎖類型和函數(shù),還有確保操作只執(zhí)行一次的機制。

頭文件內(nèi)容

namespace std
{
  class mutex;
  class recursive_mutex;
  class timed_mutex;
  class recursive_timed_mutex;

  struct adopt_lock_t;
  struct defer_lock_t;
  struct try_to_lock_t;

  constexpr adopt_lock_t adopt_lock{};
  constexpr defer_lock_t defer_lock{};
  constexpr try_to_lock_t try_to_lock{};

  template<typename LockableType>
  class lock_guard;

  template<typename LockableType>
  class unique_lock;

  template<typename LockableType1,typename... LockableType2>
  void lock(LockableType1& m1,LockableType2& m2...);

  template<typename LockableType1,typename... LockableType2>
  int try_lock(LockableType1& m1,LockableType2& m2...);

  struct once_flag;

  template<typename Callable,typename... Args>
  void call_once(once_flag& flag,Callable func,Args args...);
}

D.5.1 std::mutex類

std::mutex類型為線程提供基本的互斥和同步工具,這些工具可以用來保護共享數(shù)據(jù)?;コ饬靠梢杂脕肀Wo數(shù)據(jù),互斥量上鎖必須要調(diào)用lok()或try_lock()。當(dāng)有一個線程獲取已經(jīng)獲取了鎖,那么其他線程想要在獲取鎖的時候,會在嘗試或取鎖的時候失敗(調(diào)用try_lock())或阻塞(調(diào)用lock()),具體酌情而定。當(dāng)線程完成對共享數(shù)據(jù)的訪問,之后就必須調(diào)用unlock()對鎖進行釋放,并且允許其他線程來訪問這個共享數(shù)據(jù)。

std::mutex符合Lockable的需求。

類型定義

class mutex
{
public:
  mutex(mutex const&)=delete;
  mutex& operator=(mutex const&)=delete;

  constexpr mutex() noexcept;
  ~mutex();

  void lock();
  void unlock();
  bool try_lock();
};

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

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

聲明

constexpr mutex() noexcept;

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

后置條件
新構(gòu)造的std::mutex對象是未鎖的。

拋出

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

銷毀一個std::mutex對象。

聲明

~mutex();

先決條件
*this必須是未鎖的。

效果
銷毀*this。

拋出

std::mutex::lock 成員函數(shù)

為當(dāng)前線程獲取std::mutex上的鎖。

聲明

void lock();

先決條件
*this上必須沒有持有一個鎖。

效果
阻塞當(dāng)前線程,知道*this獲取鎖。

后置條件
*this被調(diào)用線程鎖住。

拋出
當(dāng)有錯誤產(chǎn)生,拋出std::system_error類型異常。

std::mutex::try_lock 成員函數(shù)

嘗試為當(dāng)前線程獲取std::mutex上的鎖。

聲明

bool try_lock();

先決條件
*this上必須沒有持有一個鎖。

效果
嘗試為當(dāng)前線程*this獲取上的鎖,失敗時當(dāng)前線程不會被阻塞。

返回
當(dāng)調(diào)用線程獲取鎖時,返回true。

后置條件
當(dāng)*this被調(diào)用線程鎖住,則返回true。

拋出

NOTE 該函數(shù)在獲取鎖時,可能失敗(并返回false),即使沒有其他線程持有*this上的鎖。

std::mutex::unlock 成員函數(shù)

釋放當(dāng)前線程獲取的std::mutex鎖。

聲明

void unlock();

先決條件
*this上必須持有一個鎖。

效果 釋放當(dāng)前線程獲取到*this上的鎖。任意等待獲取*this上的線程,會在該函數(shù)調(diào)用后解除阻塞。

后置條件
調(diào)用線程不在擁有*this上的鎖。

拋出

D.5.2 std::recursive_mutex類

std::recursive_mutex類型為線程提供基本的互斥和同步工具,可以用來保護共享數(shù)據(jù)?;コ饬靠梢杂脕肀Wo數(shù)據(jù),互斥量上鎖必須要調(diào)用lok()或try_lock()。當(dāng)有一個線程獲取已經(jīng)獲取了鎖,那么其他線程想要在獲取鎖的時候,會在嘗試或取鎖的時候失敗(調(diào)用try_lock())或阻塞(調(diào)用lock()),具體酌情而定。當(dāng)線程完成對共享數(shù)據(jù)的訪問,之后就必須調(diào)用unlock()對鎖進行釋放,并且允許其他線程來訪問這個共享數(shù)據(jù)。

這個互斥量是可遞歸的,所以一個線程獲取std::recursive_mutex后可以在之后繼續(xù)使用lock()或try_lock()來增加鎖的計數(shù)。只有當(dāng)線程調(diào)用unlock釋放鎖,其他線程才可能用lock()或try_lock()獲取鎖。

std::recursive_mutex符合Lockable的需求。

類型定義

class recursive_mutex
{
public:
  recursive_mutex(recursive_mutex const&)=delete;
  recursive_mutex& operator=(recursive_mutex const&)=delete;

  recursive_mutex() noexcept;
 ~recursive_mutex();

  void lock();
  void unlock();
  bool try_lock() noexcept;
};

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

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

聲明

recursive_mutex() noexcept;

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

后置條件
新構(gòu)造的std::recursive_mutex對象是未鎖的。

拋出
當(dāng)無法創(chuàng)建一個新的std::recursive_mutex時,拋出std::system_error異常。

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

銷毀一個std::recursive_mutex對象。

聲明

~recursive_mutex();

先決條件
*this必須是未鎖的。

效果
銷毀*this。

拋出

std::recursive_mutex::lock 成員函數(shù)

為當(dāng)前線程獲取std::recursive_mutex上的鎖。

聲明

void lock();

效果
阻塞線程,直到獲取*this上的鎖。

先決條件
調(diào)用線程鎖住this上的鎖。當(dāng)調(diào)用已經(jīng)持有一個this的鎖時,鎖的計數(shù)會增加1。

拋出
當(dāng)有錯誤產(chǎn)生,將拋出std::system_error異常。

std::recursive_mutex::try_lock 成員函數(shù)

嘗試為當(dāng)前線程獲取std::recursive_mutex上的鎖。

聲明

bool try_lock() noexcept;

效果
嘗試為當(dāng)前線程*this獲取上的鎖,失敗時當(dāng)前線程不會被阻塞。

返回
當(dāng)調(diào)用線程獲取鎖時,返回true;否則,返回false。

后置條件
當(dāng)*this被調(diào)用線程鎖住,則返回true。

拋出

NOTE 該函數(shù)在獲取鎖時,當(dāng)函數(shù)返回true時,*this上對鎖的計數(shù)會加一。如果當(dāng)前線程還未獲取*this上的鎖,那么該函數(shù)在獲取鎖時,可能失敗(并返回false),即使沒有其他線程持有*this上的鎖。

std::recursive_mutex::unlock 成員函數(shù)

釋放當(dāng)前線程獲取的std::recursive_mutex鎖。

聲明

void unlock();

先決條件
*this上必須持有一個鎖。

效果 釋放當(dāng)前線程獲取到*this上的鎖。如果這是*this在當(dāng)前線程上最后一個鎖,那么任意等待獲取*this上的線程,會在該函數(shù)調(diào)用后解除其中一個線程的阻塞。

后置條件
*this上鎖的計數(shù)會在該函數(shù)調(diào)用后減一。

拋出

D.5.3 std::timed_mutex類

std::timed_mutex類型在std::mutex基本互斥和同步工具的基礎(chǔ)上,讓鎖支持超時?;コ饬靠梢杂脕肀Wo數(shù)據(jù),互斥量上鎖必須要調(diào)用lok(),try_lock_for(),或try_lock_until()。當(dāng)有一個線程獲取已經(jīng)獲取了鎖,那么其他線程想要在獲取鎖的時候,會在嘗試或取鎖的時候失敗(調(diào)用try_lock())或阻塞(調(diào)用lock()),或直到想要獲取鎖可以獲取,亦或想要獲取的鎖超時(調(diào)用try_lock_for()或try_lock_until())。在線程調(diào)用unlock()對鎖進行釋放,其他線程才能獲取這個鎖被獲取(不管是調(diào)用的哪個函數(shù))。

std::timed_mutex符合TimedLockable的需求。

類型定義

class timed_mutex
{
public:
  timed_mutex(timed_mutex const&)=delete;
  timed_mutex& operator=(timed_mutex const&)=delete;

  timed_mutex();
  ~timed_mutex();

  void lock();
  void unlock();
  bool try_lock();

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

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

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

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

聲明

timed_mutex();

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

后置條件
新構(gòu)造一個未上鎖的std::timed_mutex對象。

拋出
當(dāng)無法創(chuàng)建出新的std::timed_mutex實例時,拋出std::system_error類型異常。

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

銷毀一個std::timed_mutex對象。

聲明

~timed_mutex();

先決條件
*this必須沒有上鎖。

效果
銷毀*this。

拋出

std::timed_mutex::lock 成員函數(shù)

為當(dāng)前線程獲取std::timed_mutex上的鎖。

聲明

void lock();

先決條件
調(diào)用線程不能已經(jīng)持有*this上的鎖。

效果
阻塞當(dāng)前線程,直到獲取到*this上的鎖。

后置條件
*this被調(diào)用線程鎖住。

拋出
當(dāng)有錯誤產(chǎn)生,拋出std::system_error類型異常。

std::timed_mutex::try_lock 成員函數(shù)

嘗試獲取為當(dāng)前線程獲取std::timed_mutex上的鎖。

聲明

bool try_lock();

先決條件
調(diào)用線程不能已經(jīng)持有*this上的鎖。

效果
嘗試獲取*this上的鎖,當(dāng)獲取失敗時,不阻塞調(diào)用線程。

返回
當(dāng)鎖被調(diào)用線程獲取,返回true;反之,返回false。

后置條件
當(dāng)函數(shù)返回為true,*this則被當(dāng)前線程鎖住。

拋出

NOTE 即使沒有線程已獲取*this上的鎖,函數(shù)還是有可能獲取不到鎖(并返回false)。

std::timed_mutex::try_lock_for 成員函數(shù)

嘗試獲取為當(dāng)前線程獲取std::timed_mutex上的鎖。

聲明

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

先決條件
調(diào)用線程不能已經(jīng)持有*this上的鎖。

效果
在指定的relative_time時間內(nèi),嘗試獲取*this上的鎖。當(dāng)relative_time.count()為0或負數(shù),將會立即返回,就像調(diào)用try_lock()一樣。否則,將會阻塞,直到獲取鎖或超過給定的relative_time的時間。

返回
當(dāng)鎖被調(diào)用線程獲取,返回true;反之,返回false。

后置條件
當(dāng)函數(shù)返回為true,*this則被當(dāng)前線程鎖住。

拋出

NOTE 即使沒有線程已獲取*this上的鎖,函數(shù)還是有可能獲取不到鎖(并返回false)。線程阻塞的時長可能會長于給定的時間。逝去的時間可能是由一個穩(wěn)定時鐘所決定。

std::timed_mutex::try_lock_until 成員函數(shù)

嘗試獲取為當(dāng)前線程獲取std::timed_mutex上的鎖。

聲明

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

先決條件
調(diào)用線程不能已經(jīng)持有*this上的鎖。

效果
在指定的absolute_time時間內(nèi),嘗試獲取*this上的鎖。當(dāng)absolute_time<=Clock::now()時,將會立即返回,就像調(diào)用try_lock()一樣。否則,將會阻塞,直到獲取鎖或Clock::now()返回的時間等于或超過給定的absolute_time的時間。

返回
當(dāng)鎖被調(diào)用線程獲取,返回true;反之,返回false。

后置條件
當(dāng)函數(shù)返回為true,*this則被當(dāng)前線程鎖住。

拋出

NOTE 即使沒有線程已獲取*this上的鎖,函數(shù)還是有可能獲取不到鎖(并返回false)。這里不保證調(diào)用函數(shù)要阻塞多久,只有在函數(shù)返回false后,在Clock::now()返回的時間大于或等于absolute_time時,線程才會接觸阻塞。

std::timed_mutex::unlock 成員函數(shù)

將當(dāng)前線程持有std::timed_mutex對象上的鎖進行釋放。

聲明

void unlock();

先決條件
調(diào)用線程已經(jīng)持有*this上的鎖。

效果
當(dāng)前線程釋放*this上的鎖。任一阻塞等待獲取*this上的線程,將被解除阻塞。

后置條件
*this未被調(diào)用線程上鎖。

拋出

D.5.4 std::recursive_timed_mutex類

std::recursive_timed_mutex類型在std::recursive_mutex提供的互斥和同步工具的基礎(chǔ)上,讓鎖支持超時。互斥量可以用來保護數(shù)據(jù),互斥量上鎖必須要調(diào)用lok(),try_lock_for(),或try_lock_until()。當(dāng)有一個線程獲取已經(jīng)獲取了鎖,那么其他線程想要在獲取鎖的時候,會在嘗試或取鎖的時候失敗(調(diào)用try_lock())或阻塞(調(diào)用lock()),或直到想要獲取鎖可以獲取,亦或想要獲取的鎖超時(調(diào)用try_lock_for()或try_lock_until())。在線程調(diào)用unlock()對鎖進行釋放,其他線程才能獲取這個鎖被獲取(不管是調(diào)用的哪個函數(shù))。

該互斥量是可遞歸的,所以獲取std::recursive_timed_mutex鎖的線程,可以多次的對該實例上的鎖獲取。所有的鎖將會在調(diào)用相關(guān)unlock()操作后,可由其他線程獲取該實例上的鎖。

std::recursive_timed_mutex符合TimedLockable的需求。

類型定義

class recursive_timed_mutex
{
public:
  recursive_timed_mutex(recursive_timed_mutex const&)=delete;
  recursive_timed_mutex& operator=(recursive_timed_mutex const&)=delete;

  recursive_timed_mutex();
  ~recursive_timed_mutex();

  void lock();
  void unlock();
  bool try_lock() noexcept;

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

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

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

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

聲明

recursive_timed_mutex();

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

后置條件
新構(gòu)造的std::recursive_timed_mutex實例是沒有上鎖的。

拋出
當(dāng)無法創(chuàng)建一個std::recursive_timed_mutex實例時,拋出std::system_error類異常。

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

析構(gòu)一個std::recursive_timed_mutex對象。

聲明

~recursive_timed_mutex();

先決條件
*this不能上鎖。

效果
銷毀*this。

拋出

std::recursive_timed_mutex::lock 成員函數(shù)

為當(dāng)前線程獲取std::recursive_timed_mutex對象上的鎖。

聲明

void lock();

先決條件
*this上的鎖不能被線程調(diào)用。

效果
阻塞當(dāng)前線程,直到獲取*this上的鎖。

后置條件
*this被調(diào)用線程鎖住。當(dāng)調(diào)用線程已經(jīng)獲取*this上的鎖,那么鎖的計數(shù)會再增加1。

拋出
當(dāng)錯誤出現(xiàn)時,拋出std::system_error類型異常。

std::recursive_timed_mutex::try_lock 成員函數(shù)

嘗試為當(dāng)前線程獲取std::recursive_timed_mutex對象上的鎖。

聲明

bool try_lock() noexcept;

效果
嘗試獲取*this上的鎖,當(dāng)獲取失敗時,直接不阻塞線程。

返回
當(dāng)調(diào)用線程獲取了鎖,返回true,否則返回false。

后置條件
當(dāng)函數(shù)返回true,*this會被調(diào)用線程鎖住。

拋出

NOTE 該函數(shù)在獲取鎖時,當(dāng)函數(shù)返回true時,*this上對鎖的計數(shù)會加一。如果當(dāng)前線程還未獲取*this上的鎖,那么該函數(shù)在獲取鎖時,可能失敗(并返回false),即使沒有其他線程持有*this上的鎖。

std::recursive_timed_mutex::try_lock_for 成員函數(shù)

嘗試為當(dāng)前線程獲取std::recursive_timed_mutex對象上的鎖。

聲明

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

效果
在指定時間relative_time內(nèi),嘗試為調(diào)用線程獲取*this上的鎖。當(dāng)relative_time.count()為0或負數(shù)時,將會立即返回,就像調(diào)用try_lock()一樣。否則,調(diào)用會阻塞,直到獲取相應(yīng)的鎖,或超出了relative_time時限時,調(diào)用線程解除阻塞。

返回
當(dāng)調(diào)用線程獲取了鎖,返回true,否則返回false。

后置條件
當(dāng)函數(shù)返回true,*this會被調(diào)用線程鎖住。

拋出

NOTE 該函數(shù)在獲取鎖時,當(dāng)函數(shù)返回true時,*this上對鎖的計數(shù)會加一。如果當(dāng)前線程還未獲取*this上的鎖,那么該函數(shù)在獲取鎖時,可能失敗(并返回false),即使沒有其他線程持有*this上的鎖。等待時間可能要比指定的時間長很多。逝去的時間可能由一個穩(wěn)定時鐘來計算。

std::recursive_timed_mutex::try_lock_until 成員函數(shù)

嘗試為當(dāng)前線程獲取std::recursive_timed_mutex對象上的鎖。

聲明

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

效果
在指定時間absolute_time內(nèi),嘗試為調(diào)用線程獲取*this上的鎖。當(dāng)absolute_time<=Clock::now()時,將會立即返回,就像調(diào)用try_lock()一樣。否則,調(diào)用會阻塞,直到獲取相應(yīng)的鎖,或Clock::now()返回的時間大于或等于absolute_time時,調(diào)用線程解除阻塞。

返回
當(dāng)調(diào)用線程獲取了鎖,返回true,否則返回false。

后置條件
當(dāng)函數(shù)返回true,*this會被調(diào)用線程鎖住。

拋出

NOTE 該函數(shù)在獲取鎖時,當(dāng)函數(shù)返回true時,*this上對鎖的計數(shù)會加一。如果當(dāng)前線程還未獲取*this上的鎖,那么該函數(shù)在獲取鎖時,可能失敗(并返回false),即使沒有其他線程持有*this上的鎖。這里阻塞的時間并不確定,只有當(dāng)函數(shù)返回false,然后Clock::now()返回的時間大于或等于absolute_time時,調(diào)用線程將會解除阻塞。

std::recursive_timed_mutex::unlock 成員函數(shù)

釋放當(dāng)前線程獲取到的std::recursive_timed_mutex上的鎖。

聲明

void unlock();

效果
當(dāng)前線程釋放*this上的鎖。當(dāng)*this上最后一個鎖被釋放后,任何等待獲取*this上的鎖將會解除阻塞,不過只能解除其中一個線程的阻塞。

后置條件
調(diào)用線程*this上鎖的計數(shù)減一。

拋出

D.5.5 std::lock_guard類型模板

std::lock_guard類型模板為基礎(chǔ)鎖包裝所有權(quán)。所要上鎖的互斥量類型,由模板參數(shù)Mutex來決定,并且必須符合Lockable的需求。指定的互斥量在構(gòu)造函數(shù)中上鎖,在析構(gòu)函數(shù)中解鎖。這就為互斥量鎖部分代碼提供了一個簡單的方式;當(dāng)程序運行完成時,阻塞解除,互斥量解鎖(無論是執(zhí)行到最后,還是通過控制流語句break或return,亦或是拋出異常)。

std::lock_guard是不可MoveConstructible(移動構(gòu)造), CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。

類型定義

template <class Mutex>
class lock_guard
{
public:
  typedef Mutex mutex_type;

  explicit lock_guard(mutex_type& m);
  lock_guard(mutex_type& m, adopt_lock_t);
  ~lock_guard();

  lock_guard(lock_guard const& ) = delete;
  lock_guard& operator=(lock_guard const& ) = delete;
};

std::lock_guard 自動上鎖的構(gòu)造函數(shù)

使用互斥量構(gòu)造一個std::lock_guard實例。

聲明

explicit lock_guard(mutex_type& m);

效果
通過引用提供的互斥量,構(gòu)造一個新的std::lock_guard實例,并調(diào)用m.lock()。

拋出
m.lock()拋出的任何異常。

后置條件
*this擁有m上的鎖。

std::lock_guard 獲取鎖的構(gòu)造函數(shù)

使用已提供互斥量上的鎖,構(gòu)造一個std::lock_guard實例。

聲明

lock_guard(mutex_type& m,std::adopt_lock_t);

先決條件
調(diào)用線程必須擁有m上的鎖。

效果
調(diào)用線程通過引用提供的互斥量,以及獲取m上鎖的所有權(quán),來構(gòu)造一個新的std::lock_guard實例。

拋出

后置條件
*this擁有m上的鎖。

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

銷毀一個std::lock_guard實例,并且解鎖相關(guān)互斥量。

聲明

~lock_guard();

效果
當(dāng)*this被創(chuàng)建后,調(diào)用m.unlock()。

拋出

D.5.6 std::unique_lock類型模板

std::unique_lock類型模板相較std::loc_guard提供了更通用的所有權(quán)包裝器。上鎖的互斥量可由模板參數(shù)Mutex提供,這個類型必須滿足BasicLockable的需求。雖然,通常情況下,制定的互斥量會在構(gòu)造的時候上鎖,析構(gòu)的時候解鎖,但是附加的構(gòu)造函數(shù)和成員函數(shù)提供靈活的功能?;コ饬可湘i,意味著對操作同一段代碼的線程進行阻塞;當(dāng)互斥量解鎖,就意味著阻塞解除(不論是裕興到最后,還是使用控制語句break和return,亦或是拋出異常)。std::condition_variable的鄧丹函數(shù)是需要std::unique_lock<std::mutex>實例的,并且所有std::unique_lock實例都適用于std::conditin_variable_any等待函數(shù)的Lockable參數(shù)。

當(dāng)提供的Mutex類型符合Lockable的需求,那么std::unique_lock<Mutex>也是符合Lockable的需求。此外,如果提供的Mutex類型符合TimedLockable的需求,那么std::unique_lock<Mutex>也符合TimedLockable的需求。

std::unique_lock實例是MoveConstructible(移動構(gòu)造)和MoveAssignable(移動賦值),但是不能CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值)。

類型定義

template <class Mutex>
class unique_lock
{
public:
  typedef Mutex mutex_type;

  unique_lock() noexcept;
  explicit unique_lock(mutex_type& m);
  unique_lock(mutex_type& m, adopt_lock_t);
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
  unique_lock(mutex_type& m, try_to_lock_t);

  template<typename Clock,typename Duration>
  unique_lock(
      mutex_type& m,
      std::chrono::time_point<Clock,Duration> const& absolute_time);

  template<typename Rep,typename Period>
      unique_lock(
      mutex_type& m,
      std::chrono::duration<Rep,Period> const& relative_time);

  ~unique_lock();

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

  unique_lock(unique_lock&& );
  unique_lock& operator=(unique_lock&& );

  void swap(unique_lock& other) noexcept;

  void lock();
  bool try_lock();
  template<typename Rep, typename Period>
  bool try_lock_for(
      std::chrono::duration<Rep,Period> const& relative_time);
  template<typename Clock, typename Duration>
  bool try_lock_until(
      std::chrono::time_point<Clock,Duration> const& absolute_time);
  void unlock();

  explicit operator bool() const noexcept;
  bool owns_lock() const noexcept;
  Mutex* mutex() const noexcept;
  Mutex* release() noexcept;
};

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

不使用相關(guān)互斥量,構(gòu)造一個std::unique_lock實例。

聲明

unique_lock() noexcept;

效果
構(gòu)造一個std::unique_lock實例,這個新構(gòu)造的實例沒有相關(guān)互斥量。

后置條件
this->mutex()==NULL, this->owns_lock()==false.

std::unique_lock 自動上鎖的構(gòu)造函數(shù)

使用相關(guān)互斥量,構(gòu)造一個std::unique_lock實例。

聲明

explicit unique_lock(mutex_type& m);

效果
通過提供的互斥量,構(gòu)造一個std::unique_lock實例,且調(diào)用m.lock()。

拋出
m.lock()拋出的任何異常。

后置條件
this->owns_lock()==true, this->mutex()==&m.

std::unique_lock 獲取鎖的構(gòu)造函數(shù)

使用相關(guān)互斥量和持有的鎖,構(gòu)造一個std::unique_lock實例。

聲明

unique_lock(mutex_type& m,std::adopt_lock_t);

先決條件
調(diào)用線程必須持有m上的鎖。

效果
通過提供的互斥量和已經(jīng)擁有m上的鎖,構(gòu)造一個std::unique_lock實例。

拋出

后置條件
this->owns_lock()==true, this->mutex()==&m.

std::unique_lock 遞延鎖的構(gòu)造函數(shù)

使用相關(guān)互斥量和非持有的鎖,構(gòu)造一個std::unique_lock實例。

聲明

unique_lock(mutex_type& m,std::defer_lock_t) noexcept;

效果
構(gòu)造的std::unique_lock實例引用了提供的互斥量。

拋出

后置條件
this->owns_lock()==false, this->mutex()==&m.

std::unique_lock 嘗試獲取鎖的構(gòu)造函數(shù)

使用提供的互斥量,并嘗試從互斥量上獲取鎖,從而構(gòu)造一個std::unique_lock實例。

聲明

unique_lock(mutex_type& m,std::try_to_lock_t);

先決條件
使std::unique_lock實例化的Mutex類型,必須符合Loackable的需求。

效果
構(gòu)造的std::unique_lock實例引用了提供的互斥量,且調(diào)用m.try_lock()。

拋出

后置條件
this->owns_lock()將返回m.try_lock()的結(jié)果,且this->mutex()==&m。

std::unique_lock 在給定時長內(nèi)嘗試獲取鎖的構(gòu)造函數(shù)

使用提供的互斥量,并嘗試從互斥量上獲取鎖,從而構(gòu)造一個std::unique_lock實例。

聲明

template<typename Rep,typename Period>
unique_lock(
    mutex_type& m,
    std::chrono::duration<Rep,Period> const& relative_time);

先決條件
使std::unique_lock實例化的Mutex類型,必須符合TimedLockable的需求。

效果
構(gòu)造的std::unique_lock實例引用了提供的互斥量,且調(diào)用m.try_lock_for(relative_time)。

拋出

后置條件
this->owns_lock()將返回m.try_lock_for()的結(jié)果,且this->mutex()==&m。

std::unique_lock 在給定時間點內(nèi)嘗試獲取鎖的構(gòu)造函數(shù)

使用提供的互斥量,并嘗試從互斥量上獲取鎖,從而構(gòu)造一個std::unique_lock實例。

聲明

template<typename Clock,typename Duration>
unique_lock(
    mutex_type& m,
    std::chrono::time_point<Clock,Duration> const& absolute_time);

先決條件
使std::unique_lock實例化的Mutex類型,必須符合TimedLockable的需求。

效果
構(gòu)造的std::unique_lock實例引用了提供的互斥量,且調(diào)用m.try_lock_until(absolute_time)。

拋出

后置條件
this->owns_lock()將返回m.try_lock_until()的結(jié)果,且this->mutex()==&m。

std::unique_lock 移動構(gòu)造函數(shù)

將一個已經(jīng)構(gòu)造std::unique_lock實例的所有權(quán),轉(zhuǎn)移到新的std::unique_lock實例上去。

聲明

unique_lock(unique_lock&& other) noexcept;

先決條件
使std::unique_lock實例化的Mutex類型,必須符合TimedLockable的需求。

效果
構(gòu)造的std::unique_lock實例。當(dāng)other在函數(shù)調(diào)用的時候擁有互斥量上的鎖,那么該鎖的所有權(quán)將被轉(zhuǎn)移到新構(gòu)建的std::unique_lock對象當(dāng)中去。

后置條件
對于新構(gòu)建的std::unique_lock對象x,x.mutex等價與在構(gòu)造函數(shù)調(diào)用前的other.mutex(),并且x.owns_lock()等價于函數(shù)調(diào)用前的other.owns_lock()。在調(diào)用函數(shù)后,other.mutex()==NULL,other.owns_lock()=false。

拋出

NOTE std::unique_lock對象是不可CopyConstructible(拷貝構(gòu)造),所以這里沒有拷貝構(gòu)造函數(shù),只有移動構(gòu)造函數(shù)。

std::unique_lock 移動賦值操作

將一個已經(jīng)構(gòu)造std::unique_lock實例的所有權(quán),轉(zhuǎn)移到新的std::unique_lock實例上去。

聲明

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

效果
當(dāng)this->owns_lock()返回true時,調(diào)用this->unlock()。如果other擁有mutex上的鎖,那么這個所將歸*this所有。

后置條件
this->mutex()等于在為進行賦值前的other.mutex(),并且this->owns_lock()的值與進行賦值操作前的other.owns_lock()相等。other.mutex()==NULL, other.owns_lock()==false。

拋出

NOTE std::unique_lock對象是不可CopyAssignable(拷貝賦值),所以這里沒有拷貝賦值函數(shù),只有移動賦值函數(shù)。

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

銷毀一個std::unique_lock實例,如果該實例擁有鎖,那么會將相關(guān)互斥量進行解鎖。

聲明

~unique_lock();

效果
當(dāng)this->owns_lock()返回true時,調(diào)用this->mutex()->unlock()。

拋出

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

交換std::unique_lock實例中相關(guān)的所有權(quán)。

聲明

void swap(unique_lock& other) noexcept;

效果
如果other在調(diào)用該函數(shù)前擁有互斥量上的鎖,那么這個鎖將歸*this所有。如果*this在調(diào)用哎函數(shù)前擁有互斥量上的鎖,那么這個鎖將歸other所有。

拋出

std::unique_lock 上非成員函數(shù)swap

交換std::unique_lock實例中相關(guān)的所有權(quán)。

聲明

void swap(unique_lock& lhs,unique_lock& rhs) noexcept;

效果
lhs.swap(rhs)

拋出

std::unique_lock::lock 成員函數(shù)

獲取與*this相關(guān)互斥量上的鎖。

聲明

void lock();

先決條件
this->mutex()!=NULL, this->owns_lock()==false.

效果
調(diào)用this->mutex()->lock()。

拋出
拋出任何this->mutex()->lock()所拋出的異常。當(dāng)this->mutex()==NULL,拋出std::sytem_error類型異常,錯誤碼為std::errc::operation_not_permitted。當(dāng)this->owns_lock()==true時,拋出std::system_error,錯誤碼為std::errc::resource_deadlock_would_occur。

后置條件
this->owns_lock()==true。

std::unique_lock::try_lock 成員函數(shù)

嘗試獲取與*this相關(guān)互斥量上的鎖。

聲明

bool try_lock();

先決條件
std::unique_lock實例化說是用的Mutex類型,必須滿足Lockable需求。this->mutex()!=NULL, this->owns_lock()==false。

效果
調(diào)用this->mutex()->try_lock()。

拋出
拋出任何this->mutex()->try_lock()所拋出的異常。當(dāng)this->mutex()==NULL,拋出std::sytem_error類型異常,錯誤碼為std::errc::operation_not_permitted。當(dāng)this->owns_lock()==true時,拋出std::system_error,錯誤碼為std::errc::resource_deadlock_would_occur。

后置條件
當(dāng)函數(shù)返回true時,this->ows_lock()==true,否則this->owns_lock()==false。

std::unique_lock::unlock 成員函數(shù)

釋放與*this相關(guān)互斥量上的鎖。

聲明

void unlock();

先決條件
this->mutex()!=NULL, this->owns_lock()==true。

拋出
拋出任何this->mutex()->unlock()所拋出的異常。當(dāng)this->owns_lock()==false時,拋出std::system_error,錯誤碼為std::errc::operation_not_permitted。

后置條件
this->owns_lock()==false。

std::unique_lock::try_lock_for 成員函數(shù)

在指定時間內(nèi)嘗試獲取與*this相關(guān)互斥量上的鎖。

聲明

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

先決條件
std::unique_lock實例化說是用的Mutex類型,必須滿足TimedLockable需求。this->mutex()!=NULL, this->owns_lock()==false。

效果
調(diào)用this->mutex()->try_lock_for(relative_time)。

返回
當(dāng)this->mutex()->try_lock_for()返回true,返回true,否則返回false。

拋出
拋出任何this->mutex()->try_lock_for()所拋出的異常。當(dāng)this->mutex()==NULL,拋出std::sytem_error類型異常,錯誤碼為std::errc::operation_not_permitted。當(dāng)this->owns_lock()==true時,拋出std::system_error,錯誤碼為std::errc::resource_deadlock_would_occur

后置條件
當(dāng)函數(shù)返回true時,this->ows_lock()==true,否則this->owns_lock()==false。

std::unique_lock::try_lock_until 成員函數(shù)

在指定時間點嘗試獲取與*this相關(guān)互斥量上的鎖。

聲明

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

先決條件
std::unique_lock實例化說是用的Mutex類型,必須滿足TimedLockable需求。this->mutex()!=NULL, this->owns_lock()==false。

效果
調(diào)用this->mutex()->try_lock_until(absolute_time)。

返回
當(dāng)this->mutex()->try_lock_for()返回true,返回true,否則返回false。

拋出
拋出任何this->mutex()->try_lock_for()所拋出的異常。當(dāng)this->mutex()==NULL,拋出std::sytem_error類型異常,錯誤碼為std::errc::operation_not_permitted。當(dāng)this->owns_lock()==true時,拋出std::system_error,錯誤碼為std::errc::resource_deadlock_would_occur。

后置條件
當(dāng)函數(shù)返回true時,this->ows_lock()==true,否則this->owns_lock()==false。

std::unique_lock::operator bool成員函數(shù)

檢查*this是否擁有一個互斥量上的鎖。

聲明

explicit operator bool() const noexcept;

返回
this->owns_lock()

拋出

NOTE 這是一個explicit轉(zhuǎn)換操作,所以當(dāng)這樣的操作在上下文中只能被隱式的調(diào)用,所返回的結(jié)果需要被當(dāng)做一個布爾量進行使用,而非僅僅作為整型數(shù)0或1。

std::unique_lock::owns_lock 成員函數(shù)

檢查*this是否擁有一個互斥量上的鎖。

聲明

bool owns_lock() const noexcept;

返回
當(dāng)*this持有一個互斥量的鎖,返回true;否則,返回false。

拋出

std::unique_lock::mutex 成員函數(shù)

當(dāng)*this具有相關(guān)互斥量時,返回這個互斥量

聲明

mutex_type* mutex() const noexcept;

返回
當(dāng)*this有相關(guān)互斥量,則返回該互斥量;否則,返回NULL。

拋出

std::unique_lock::release 成員函數(shù)

當(dāng)*this具有相關(guān)互斥量時,返回這個互斥量,并將這個互斥量進行釋放。

聲明

mutex_type* release() noexcept;

效果
將*this與相關(guān)的互斥量之間的關(guān)系解除,同時解除所有持有鎖的所有權(quán)。

返回
返回與*this相關(guān)的互斥量指針,如果沒有相關(guān)的互斥量,則返回NULL。

后置條件
this->mutex()==NULL, this->owns_lock()==false。

拋出

NOTE 如果this->owns_lock()在調(diào)用該函數(shù)前返回true,那么調(diào)用者則有責(zé)任里解除互斥量上的鎖。

D.5.7 std::lock函數(shù)模板

std::lock函數(shù)模板提供同時鎖住多個互斥量的功能,且不會有因改變鎖的一致性而導(dǎo)致的死鎖。

聲明

template<typename LockableType1,typename... LockableType2>
void lock(LockableType1& m1,LockableType2& m2...);

先決條件
提供的可鎖對象LockableType1, LockableType2...,需要滿足Lockable的需求。

效果
使用未指定順序調(diào)用lock(),try_lock()獲取每個可鎖對象(m1, m2...)上的鎖,還有unlock()成員來避免這個類型陷入死鎖。

后置條件
當(dāng)前線程擁有提供的所有可鎖對象上的鎖。

拋出
任何lock(), try_lock()和unlock()拋出的異常。

NOTE 如果一個異常由std::lock所傳播開來,當(dāng)可鎖對象上有鎖被lock()或try_lock()獲取,那么unlock()會使用在這些可鎖對象上。

D.5.8 std::try_lock函數(shù)模板

std::try_lock函數(shù)模板允許嘗試獲取一組可鎖對象上的鎖,所以要不全部獲取,要不一個都不獲取。

聲明

template<typename LockableType1,typename... LockableType2>
int try_lock(LockableType1& m1,LockableType2& m2...);

先決條件
提供的可鎖對象LockableType1, LockableType2...,需要滿足Lockable的需求。

效果
使用try_lock()嘗試從提供的可鎖對象m1,m2...上逐個獲取鎖。當(dāng)鎖在之前獲取過,但被當(dāng)前線程使用unlock()對相關(guān)可鎖對象進行了釋放后,try_lock()會返回false或拋出一個異常。

返回
當(dāng)所有鎖都已獲取(每個互斥量調(diào)用try_lock()返回true),則返回-1,否則返回以0為基數(shù)的數(shù)字,其值為調(diào)用try_lock()返回false的個數(shù)。

后置條件
當(dāng)函數(shù)返回-1,當(dāng)前線程獲取從每個可鎖對象上都獲取一個鎖。否則,通過該調(diào)用獲取的任何鎖都將被釋放。

拋出
try_lock()拋出的任何異常。

NOTE 如果一個異常由std::try_lock所傳播開來,則通過try_lock()獲取鎖對象,將會調(diào)用unlock()解除對鎖的持有。

D.5.9 std::once_flag類