以下是 C++ 中常见的互斥同步工具和机制的总结,包括它们的头文件、初始化、常用操作和销毁方法。
1. 互斥量(Mutex)
- 头文件:
<mutex> - 初始化:
std::mutex mtx;// 默认构造函数初始化为未锁定状态
- 操作:
std::lock_guard<std::mutex> guard(mtx);// 自动加锁并在作用域结束时自动解锁std::unique_lock<std::mutex> lock(mtx);// 手动控制锁的加锁和解锁mtx.lock();// 手动加锁mtx.unlock();// 手动解锁
- 销毁: 无需显式销毁,
std::mutex在超出作用域时自动析构。
2. 读写锁(Shared Mutex)
- 头文件:
<shared_mutex> - 初始化:
std::shared_mutex smtx;// 默认构造函数
- 操作:
std::unique_lock<std::shared_mutex> lock(smtx);// 获取独占锁std::shared_lock<std::shared_mutex> lock(smtx);// 获取共享锁smtx.lock();// 获取独占锁smtx.unlock();// 解锁smtx.lock_shared();// 获取共享锁smtx.unlock_shared();// 解锁共享锁
- 销毁: 无需显式销毁,
std::shared_mutex在超出作用域时自动析构。
3. 条件变量(Condition Variable)
- 头文件:
<condition_variable> - 初始化:
std::condition_variable cv;
- 操作:
std::unique_lock<std::mutex> lock(mtx);cv.wait(lock);// 等待条件满足,释放锁cv.wait_for(lock, duration);// 等待条件或超时cv.wait_until(lock, time_point);// 等待直到指定时间点cv.notify_one();// 唤醒一个等待的线程cv.notify_all();// 唤醒所有等待的线程
- 销毁: 无需显式销毁,
std::condition_variable在超出作用域时自动析构。
4. 原子操作(Atomic Operations)
- 头文件:
<atomic> - 初始化:
std::atomic<int> counter(0);// 初始化为 0std::atomic<bool> flag(true);// 初始化为 true
- 操作:
counter.load();// 获取原子值counter.store(value);// 设置原子值counter.fetch_add(1);// 原子加法counter.fetch_sub(1);// 原子减法counter.compare_exchange_weak(expected, desired);// 比较并交换(CAS)
- 销毁: 无需显式销毁,
std::atomic在超出作用域时自动析构。
5. 二元信号量(Binary Semaphore)
- 头文件:
<semaphore>(C++20) - 初始化:
std::binary_semaphore sem(0);// 初始化为 0(表示锁定)std::binary_semaphore sem(1);// 初始化为 1(表示解锁)
- 操作:
sem.acquire();// 获取信号量,如果值为 0,则阻塞sem.release();// 释放信号量,将值设为 1,唤醒阻塞线程
- 销毁: 无需显式销毁,
std::binary_semaphore在超出作用域时自动析构。
6. 信号量(Counting Semaphore)
- 头文件:
<semaphore>(C++20) - 初始化:
std::counting_semaphore<3> sem(3);// 初始化为 3(表示最多允许 3 个线程)
- 操作:
sem.acquire();// 获取信号量,减少计数sem.release();// 释放信号量,增加计数
- 销毁: 无需显式销毁,
std::counting_semaphore在超出作用域时自动析构。
7. 屏障(Barrier)
- 头文件:
<barrier>(C++20) - 初始化:
std::barrier barrier(3);// 初始化,表示 3 个线程同步
- 操作:
barrier.arrive_and_wait();// 线程到达屏障并等待,直到所有线程都到达
- 销毁: 无需显式销毁,
std::barrier在超出作用域时自动析构。
8. 临界区(Critical Section)
临界区通常用于 Windows 平台,它是一种轻量级的互斥工具。
- 头文件:
<windows.h> - 初始化:
CRITICAL_SECTION cs;InitializeCriticalSection(&cs);
- 操作:
EnterCriticalSection(&cs);// 获取临界区LeaveCriticalSection(&cs);// 释放临界区
- 销毁:
DeleteCriticalSection(&cs);// 删除临界区
9. 互斥量的标准类(例如 std::lock_guard 和 std::unique_lock)
这些类用于简化锁的管理,自动加锁和解锁。
- 头文件:
<mutex> - 操作:
std::lock_guard<std::mutex> guard(mtx);// 自动加锁,作用域结束时自动解锁std::unique_lock<std::mutex> lock(mtx);// 手动控制加锁和解锁
总结
| 工具 | 头文件 | 初始化 | 操作 | 销毁 |
|---|---|---|---|---|
| 互斥量(Mutex) | <mutex> |
std::mutex mtx; |
mtx.lock(); mtx.unlock(); |
自动销毁 |
| 读写锁(Shared Mutex) | <shared_mutex> |
std::shared_mutex smtx; |
lock_shared(); unlock_shared(); |
自动销毁 |
| 条件变量(Condition Variable) | <condition_variable> |
std::condition_variable cv; |
cv.wait(); cv.notify_one(); |
自动销毁 |
| 原子操作(Atomic) | <atomic> |
std::atomic<int> counter(0); |
counter.load(); counter.store(value); |
自动销毁 |
| 二元信号量(Binary Semaphore) | <semaphore> (C++20) |
std::binary_semaphore sem(0); |
sem.acquire(); sem.release(); |
自动销毁 |
| 信号量(Counting Semaphore) | <semaphore> (C++20) |
std::counting_semaphore<3> sem(3); |
sem.acquire(); sem.release(); |
自动销毁 |
| 屏障(Barrier) | <barrier> (C++20) |
std::barrier barrier(3); |
barrier.arrive_and_wait(); |
自动销毁 |
| 临界区(Critical Section) | <windows.h> |
InitializeCriticalSection(&cs); |
EnterCriticalSection(&cs); |
DeleteCriticalSection(&cs); |
每种机制适用于不同的同步场景,选择时需要根据具体需求(例如是否需要支持多个线程同时读取、是否需要无锁操作等)进行选择。