互斥锁与原子操作
std::mutex/lock_guard、std::atomic、内存序、死锁避免
互斥锁与原子操作
数据竞争用锁或原子操作解决——std::mutex + std::lock_guard 是标配,std::atomic 更轻量。
学完本章你将: 掌握 std::mutex/lock_guard、std::atomic、死锁避免。
mutex + lock_guard
cpp
#include <mutex>
std::mutex mtx;
int counter = 0;
void increment() {
for (int i = 0; i < 100000; i++) {
std::lock_guard<std::mutex> lock(mtx); // RAII 自动解锁
counter++;
}
}
std::thread t1(increment);
std::thread t2(increment);
t1.join(); t2.join();
std::cout << counter; // 200000——正确!
std::atomic —— 无锁原子操作
cpp
#include <atomic>
std::atomic<int> counter{0};
void increment() {
for (int i = 0; i < 100000; i++) {
counter++; // 原子操作——不需要锁,更高性能
}
}
// 适用:简单计数、标志位
// 不适用:复杂数据结构(还是用 mutex)
死锁避免
cpp
std::mutex m1, m2;
// ❌ 死锁——两个线程以不同顺序获取锁
void f1() { lock(m1); lock(m2); }
void f2() { lock(m2); lock(m1); }
// ✅ 用 std::lock 同时获取多个锁
void safe() {
std::lock(m1, m2); // 原子地锁定多个
std::lock_guard<std::mutex> lk1(m1, std::adopt_lock); // 接管已锁的 mutex
std::lock_guard<std::mutex> lk2(m2, std::adopt_lock);
}
其他锁类型
cpp
std::shared_mutex smtx; // C++17 读写锁
std::recursive_mutex rmtx; // 同一线程可多次 lock
std::timed_mutex tmtx; // 带超时的锁