天天看點

C++11并發與多線程筆記(6) unique_lock(類模闆)詳解

第六節 unique_lock(類模闆)詳解

C++11并發與多線程筆記(6) unique_lock(類模闆)詳解

1.unique_lock取代lock_guard

unique_lock比lock_guard靈活很多(多出來很多用法),效率差一點。

unique_lock myUniLock(myMutex);

2.unique_lock的第二個參數

2.1 std::adopt_lock:

  • 表示這個互斥量已經被lock(),即不需要在構造函數中lock這個互斥量了。
  • 前提:必須提前lock
  • lock_guard中也可以用這個參數

2.2 std::try_to_lock:

  • 嘗試用mutx的lock()去鎖定這個mutex,但如果沒有鎖定成功,會立即傳回,不會阻塞在那裡;
  • 使用try_to_lock的原因是防止其他的線程鎖定mutex太長時間,導緻本線程一直阻塞在lock這個地方
  • 前提:不能提前lock();
  • owns_locks()方法判斷是否拿到鎖,如拿到傳回true

2.3 std::defer_lock:

  • 如果沒有第二個參數就對mutex進行加鎖,加上defer_lock是始化了一個沒有加鎖的mutex
  • 不給它加鎖的目的是以後可以調用unique_lock的一些方法
  • 前提:不能提前lock

3.unique_lock的成員函數(前三個與std::defer_lock聯合使用)

3.1 lock():加鎖。

unique_lock<mutex> myUniLock(myMutex, defer_lock);
myUniLock.lock();
           

不用自己unlock();

3.2 unlock():解鎖。

unique_lock<mutex> myUniLock(myMutex, defer_lock);
myUniLock.lock();
//處理一些共享代碼
myUniLock.unlock();
//處理一些非共享代碼
myUniLock.lock();
//處理一些共享代碼
           

因為一些非共享代碼要處理,可以暫時先unlock(),用其他線程把它們處理了,處理完後再lock()。

3.3 try_lock():嘗試給互斥量加鎖

如果拿不到鎖,傳回false,否則傳回true。

3.4 release():

  • unique_lock

    myUniLock(myMutex);相當于把myMutex和myUniLock綁定在了一起,release()就是解除綁定,傳回它所管理的mutex對象的指針,并釋放所有權

  • mutex* ptx =

    myUniLock.release();所有權由ptx接管,如果原來mutex對象處理加鎖狀态,就需要ptx在以後進行解鎖了。

lock的代碼段越少,執行越快,整個程式的運作效率越高。

a.鎖住的代碼少,叫做粒度細,執行效率高;

b.鎖住的代碼多,叫做粒度粗,執行效率低;

4.unique_lock所有權的傳遞

unique_lock myUniLock(myMutex);把myMutex和myUniLock綁定在了一起,也就是myUniLock擁有myMutex的所有權

1. 使用move轉移

  • myUniLock擁有myMutex的所有權,myUniLock可以把自己對myMutex的所有權轉移,但是不能複制。
  • unique_lock myUniLock2(std::move(myUniLock));

    現在myUniLock2擁有myMutex的所有權。

2. 在函數中return一個臨時變量,即可以實作轉移

unique_lock<mutex> aFunction()
{
    unique_lock<mutex> myUniLock(myMutex);
    //移動構造函數那裡講從函數傳回一個局部的unique_lock對象是可以的
    //傳回這種局部對象會導緻系統生成臨時的unique_lock對象,并調用unique_lock的移動構造函數
    return myUniLock;
}
           

繼續閱讀