1. 程式人生 > >C++中的std::lock_guard和std::unique_lock

C++中的std::lock_guard和std::unique_lock

std::lock_guard

這是最簡單的一個管理鎖的物件。只有構造和解構函式,在構造的時候加鎖,析構的時候解鎖,解鎖後就不能使用該物件再加鎖了。可以避免使用std::mutex時忘記解鎖的情況,同時可以方便處理異常。

簡單的例項:

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <stdexcept>

std::mutex mtx;

void print_even(int n) {
    if
(n % 2 == 0) { std::cout << n << " is even\n"; } else { throw std::logic_error("not even\n"); } } void print_thread_id(int id) { try { // 在這裡,try塊是單獨一個部分,離開塊之後,鎖就自動析構了 std::lock_guard<std::mutex>lck(mtx); print_even(id); } catch(std::
logic_error&) { std::cout << "[exception caught]\n"; } } int main() { // 建立執行緒組 std::vector<std::thread>threads; for(int i = 0; i < 10; ++i) { threads.emplace_back(std::thread(print_thread_id, i + 1)); } // 所有執行緒等待歸併 for(auto& th : threads)
{ th.join(); } return 0; } /* 輸出結果: [exception caught] 2 is even [exception caught] 4 is even [exception caught] 6 is even [exception caught] 8 is even [exception caught] 10 is even */

std::unique_lock

擁有std::lock_guard所有的功能,但是更加靈活,也有更多的介面;時間和空間要求也更高了。

給出常用的5個建構函式:

unique_lock() noexcept;                                   // (1)
explicit unique_lock (mutex_type& m);                     // (2)
unique_lock (mutex_type& m, try_to_lock_t tag);           // (3)
unique_lock (mutex_type& m, defer_lock_t tag) noexcept;   // (4)
unique_lock (mutex_type& m, adopt_lock_t tag);            // (5)
  1. 僅僅定義一個物件,不管理任何鎖物件
  2. 管理鎖物件m,同時嘗試呼叫m.lock()進行加鎖,如果別的unique_lock已經管理了當前鎖m,那麼當前執行緒阻塞。
  3. 管理鎖物件m,如果上鎖失敗,執行緒不會阻塞
  4. 管理鎖物件m,初始化的時候不會鎖住m
  5. 管理鎖物件m,而且m應當是一個已經被當前執行緒鎖住的Mutex物件

常用的成員函式:

  • try_lock上鎖成功返回true,否則返回false
  • try_lock_for,呼叫管理物件的try_lock_for函式,成功返回true,失敗返回false
  • try_lock_until,同try_lock_for
  • unlock,呼叫管理物件的unlock函式
  • release,返回管理鎖的指標,並釋放管理權
  • owns_lock,判斷是否擁有了鎖。