1. 互斥锁(std::mutex
)
✅ 简介
- 最常用的线程同步工具。
- 保证同一时间只能有一个线程访问临界区。
✅ 使用方式
#include <mutex>
std::mutex mtx;
void safeFunction() {
std::lock_guard<std::mutex> lock(mtx);
}
✅ 优点
- 简单易用。
- 可配合
std::lock_guard
或 std::unique_lock
自动释放锁。
❌ 缺点
- 遇到锁竞争时,线程会挂起,涉及上下文切换,代价较高。
2. 自旋锁(Spinlock)
✅ 简介
- 忙等待方式的锁,线程会在获取不到锁时不断循环尝试。
- 适合临界区执行时间非常短的场景。
✅ 简易实现(非标准库提供)
#include <atomic>
class Spinlock {
private:
std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
void lock() {
while (flag.test_and_set(std::memory_order_acquire));
}
void unlock() {
flag.clear(std::memory_order_release);
}
};
✅ 优点
- 避免线程上下文切换,性能好于互斥锁(在锁竞争低、持有时间短的场景下)。
❌ 缺点
3. 读写锁(std::shared_mutex
)
✅ 简介
- 允许多个线程并发读,但写操作是独占的。
- C++17 起引入
std::shared_mutex
和 std::shared_lock
。
✅ 示例
#include <shared_mutex>
std::shared_mutex rw_mutex;
void reader() {
std::shared_lock<std::shared_mutex> lock(rw_mutex);
}
void writer() {
std::unique_lock<std::shared_mutex> lock(rw_mutex);
}
✅ 优点
❌ 缺点
4. 原子锁(基于 std::atomic
)
✅ 简介
- 利用原子变量实现无锁同步(lock-free)。
- 适合轻量级同步,比如计数器、自增等。
✅ 示例
#include <atomic>
std::atomic<int> counter = 0;
void increment() {
counter.fetch_add(1, std::memory_order_relaxed);
}
✅ 优点
❌ 缺点
- 仅适用于非常简单的场景,复杂逻辑使用困难。
- 易于出错;难以实现复杂的同步逻辑。
🔚 总结对比
锁类型 | 是否阻塞 | 性能 | 适用场景 | 是否标准库支持 |
---|
互斥锁 | 是 | 中 | 通用 | ✅ C++11 |
自旋锁 | 否 | 高(短时) | 临界区极短,高性能要求 | ❌ 手动实现 |
读写锁 | 读非阻塞 | 高 | 读多写少场景 | ✅ C++17 |
原子锁 | 否 | 极高 | 简单同步(计数器等) | ✅ C++11 |