C++ 线程同步

以下是C++中线程同步的五种核心方式及其详细对比,结合示例与特性分析:


  1. 互斥量(Mutex)
    原理:独占锁,确保同一时刻仅一个线程访问共享资源。
    C++11支持:std::mutexstd::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自动释放锁,避免忘记解锁导致死锁
    劣势:
  • 可能引起线程阻塞等待

  1. 条件变量(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中检查条件)

  1. 临界区(Critical Section,Windows特有)
    原理:轻量级互斥锁,仅限同一进程内线程使用
    Windows API:CRITICAL_SECTIONEnterCriticalSection()/LeaveCriticalSection()
    示例:
#include <Windows.h>
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
 
void safe_increment() {
    EnterCriticalSection(&cs);
    // 操作共享资源 
    LeaveCriticalSection(&cs);
}

优势:

  • 比内核对象(如Mutex)更快,因无需切换内核态
    劣势:
  • 仅限进程内同步,不可跨进程

  1. 事件(Event,Windows特有)
    原理:内核对象,通过信号状态控制线程阻塞/唤醒
    类型:
  • 自动重置事件:唤醒单一线程后自动重置为无信号。
  • 手动重置事件:需手动调用ResetEvent()重置。
    示例:
HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); // 手动重置事件 
 
void wait_thread() {
    WaitForSingleObject(event, INFINITE); // 等待事件
    // 执行任务...
}
 
void signal_thread() {
    SetEvent(event); // 触发事件 
}

优势:

  • 精确控制线程唤醒顺序
    劣势:
  • 内核对象调用开销较大

  1. 原子操作(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 )。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯文小提莫

努力提高作品质量

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值