std::lock_guard
來自 cppreference.com
定義於標頭檔案 <mutex> |
||
template< class Mutex > class lock_guard; |
(C++11 起) | |
類lock_guard
是一個互斥體封裝器,它提供了一個方便的RAII風格機制,用於在作用域塊的持續時間內擁有一個互斥體。
當一個lock_guard
物件被建立時,它會嘗試獲取它被賦予的互斥體的所有權。當控制離開建立lock_guard
物件的作用域時,lock_guard
會被銷燬,互斥體也會被釋放。
lock_guard
類不可複製。
目錄 |
[編輯] 模板引數
Mutex | - | 要鎖定的互斥體型別。該型別必須滿足BasicLockable要求 |
[編輯] 成員型別
成員型別 | 定義 |
mutex_type
|
Mutex |
[編輯] 成員函式
構造一個lock_guard ,可選地鎖定給定的互斥體(公共成員函式) | |
銷燬lock_guard 物件,解鎖底層互斥體(公共成員函式) | |
operator= [已刪除] |
不可複製賦值 (公共成員函式) |
[編輯] 注意
一個常見的初學者錯誤是“忘記”給lock_guard
變數命名,例如std::lock_guard(mtx);(它預設構造一個名為mtx
的lock_guard
變數)或std::lock_guard{mtx};(它構造一個prvalue物件,該物件立即被銷燬),從而實際上沒有構造一個在作用域剩餘時間內持有互斥體的鎖。
std::scoped_lock 為 |
(C++17 起) |
[編輯] 示例
演示了兩個執行緒對 volatile 變數的安全和不安全增量。
執行此程式碼
#include <iostream> #include <mutex> #include <string_view> #include <syncstream> #include <thread> volatile int g_i = 0; std::mutex g_i_mutex; // protects g_i void safe_increment(int iterations) { const std::lock_guard<std::mutex> lock(g_i_mutex); while (iterations-- > 0) g_i = g_i + 1; std::cout << "thread #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n'; // g_i_mutex is automatically released when lock goes out of scope } void unsafe_increment(int iterations) { while (iterations-- > 0) g_i = g_i + 1; std::osyncstream(std::cout) << "thread #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n'; } int main() { auto test = [](std::string_view fun_name, auto fun) { g_i = 0; std::cout << fun_name << ":\nbefore, g_i: " << g_i << '\n'; { std::jthread t1(fun, 1'000'000); std::jthread t2(fun, 1'000'000); } std::cout << "after, g_i: " << g_i << "\n\n"; }; test("safe_increment", safe_increment); test("unsafe_increment", unsafe_increment); }
可能的輸出
safe_increment: before, g_i: 0 thread #140121493231360, g_i: 1000000 thread #140121484838656, g_i: 2000000 after, g_i: 2000000 unsafe_increment: before, g_i: 0 thread #140121484838656, g_i: 1028945 thread #140121493231360, g_i: 1034337 after, g_i: 1034337
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 2981 | C++17 | 提供了冗餘的從 lock_guard<Mutex> 推導指南 |
已移除 |
[編輯] 另請參閱
(C++11) |
實現可移動的互斥體所有權包裝器 (類模板) |
(C++17) |
用於多個互斥體的死鎖避免 RAII 包裝器 (類模板) |