在多線程程式設計中,保護共享資料免受競態條件影響至關重要。C++11 標準庫(當時稱為 C++0x)提供了 std::mutex 系列互斥鎖,分為四種類型以滿足不同場景需求:
lock_guard 與 unique_lockC++ 採用 RAII(資源獲取即初始化)機制管理鎖的生命週期。兩大核心模板類別:
defer_lock)、超時嘗試鎖定、手動解鎖與所有權轉移,配合 timed_mutex 使用時威力最大。std::mutex m;
MyClass data;
void foo() {
std::lock_guard<std::mutex> lk(m); // 自動鎖定/解鎖
process(data);
} // 離開作用域自動解鎖
// 帶超時的鎖定嘗試
std::timed_mutex tm;
void timed_foo() {
std::unique_lock<std::timed_mutex> lk(tm, std::chrono::milliseconds(3));
if (lk) { // 成功獲取鎖
process(data);
}
} // 自動解鎖
std::lock 多鎖原子獲取當需要同時鎖定多個互斥量時,若各線程獲取順序不一致極易導致死鎖。C++11 提供 std::lock 一次性原子性地鎖定多個鎖,完全避免死鎖風險。
struct Account {
std::mutex m;
int balance;
};
void transfer(Account& a, Account& b) {
// 使用 defer_lock 延遲鎖定
std::unique_lock<std::mutex> lock_a(a.m, std::defer_lock);
std::unique_lock<std::mutex> lock_b(b.m, std::defer_lock);
// 原子性同時鎖定兩個互斥量
std::lock(lock_a, lock_b);
// 安全操作兩個帳戶資料
// ...
}
若線程 1 執行 transfer(x, y) 而線程 2 執行 transfer(y, x),傳統逐個鎖定方式必然死鎖;使用 std::lock 則完全安全。
掌握四種互斥鎖特性、善用 RAII 鎖管理類別、以及多鎖場景下的 std::lock,是編寫高效、安全 C++ 多線程程式的基石。