C++的同步互斥机制

以下是 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); // 初始化为 0
    • std::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_guardstd::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);

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