以下是 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); |
每种机制适用于不同的同步场景,选择时需要根据具体需求(例如是否需要支持多个线程同时读取、是否需要无锁操作等)进行选择。