C++中的std::lock_guard和std::unique_lock
阿新 • • 發佈:2018-11-19
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)
- 僅僅定義一個物件,不管理任何鎖物件
- 管理鎖物件
m
,同時嘗試呼叫m.lock()
進行加鎖,如果別的unique_lock
已經管理了當前鎖m
,那麼當前執行緒阻塞。 - 管理鎖物件
m
,如果上鎖失敗,執行緒不會阻塞 - 管理鎖物件
m
,初始化的時候不會鎖住m
- 管理鎖物件
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
,判斷是否擁有了鎖。