以下是C++中线程同步的五种核心方式及其详细对比,结合示例与特性分析:
- 互斥量(Mutex)
原理:独占锁,确保同一时刻仅一个线程访问共享资源。
C++11支持:std::mutex、std::lock_guard(自动管理锁生命周期)
示例:
#include <mutex>
#include <thread>
std::mutex mtx;
int shared_data = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁/解锁
for (int i = 0; i < 10000; ++i) ++shared_data;
}
int main() {
std::thread t1(increment), t2(increment);
t1.join(); t2.join();
std::cout << shared_data; // 输出20000
}
优势:
- 简单高效,适合大部分数据保护场景
lock_guard自动释放锁,避免忘记解锁导致死锁
劣势:- 可能引起线程阻塞等待
- 条件变量(Condition Variable)
原理:线程等待特定条件成立后继续执行,常与互斥量配合使用。
C++11支持:std::condition_variable
示例(生产者-消费者模型):
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool data_ready = false;
void consumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return data_ready; }); // 等待条件成立
// 消费数据...
}
void producer() {
{
std::lock_guard<std::mutex> lock(mtx);
data_ready = true;
}
cv.notify_one(); // 通知等待线程
}
优势:
- 减少无效轮询,节省CPU资源
劣势: - 需严格避免“虚假唤醒”(需在
wait中检查条件)
- 临界区(Critical Section,Windows特有)
原理:轻量级互斥锁,仅限同一进程内线程使用
Windows API:CRITICAL_SECTION、EnterCriticalSection()/LeaveCriticalSection()。
示例:
#include <Windows.h>
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
void safe_increment() {
EnterCriticalSection(&cs);
// 操作共享资源
LeaveCriticalSection(&cs);
}
优势:
- 比内核对象(如Mutex)更快,因无需切换内核态
劣势: - 仅限进程内同步,不可跨进程
- 事件(Event,Windows特有)
原理:内核对象,通过信号状态控制线程阻塞/唤醒
类型:
- 自动重置事件:唤醒单一线程后自动重置为无信号。
- 手动重置事件:需手动调用
ResetEvent()重置。
示例:
HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); // 手动重置事件
void wait_thread() {
WaitForSingleObject(event, INFINITE); // 等待事件
// 执行任务...
}
void signal_thread() {
SetEvent(event); // 触发事件
}
优势:
- 精确控制线程唤醒顺序
劣势: - 内核对象调用开销较大
- 原子操作(Atomic)
原理:通过硬件指令保证操作的不可分割性
C++11支持:std::atomic<T>。
示例:
#include <atomic>
std::atomic<int> counter(0);
void increment_atomic() {
for (int i = 0; i < 10000; ++i) counter.fetch_add(1);
} // 无需显式锁
优势:
- 性能最优(无锁设计)
劣势: - 仅适用于简单数据类型(如整数、指针)
对比总结
| 方式 | 适用场景 | 性能 | 跨进程 | C++标准支持 |
|---|---|---|---|---|
| 互斥量 | 通用数据保护 | 中高 | ❌ | ✔️ (C++11) |
| 条件变量 | 线程间状态协作(如生产者-消费者) | 中 | ❌ | ✔️ (C++11) |
| 临界区(Windows) | 进程内高效同步 | 最高 | ❌ | ❌ |
| 事件(Windows) | 精细控制线程唤醒 | 低(内核调用) | ✔️ | ❌ |
| 原子操作 | 计数器、标志位等简单操作 | 极高 | ❌ | ✔️ (C++11) |
💡 选择建议:
- 优先使用
std::mutex+std::lock_guard满足多数需求- 需等待条件时用条件变量替代轮询
- 高性能场景选原子操作或临界区(Windows)
- 跨进程同步需用事件或互斥量(
CreateMutex)。

1万+

被折叠的 条评论
为什么被折叠?



