C++ 锁机制(Lock API)详解

📌 C++ 锁机制(Lock API)详解

在 C++ 多线程编程中,锁(Lock)主要用于保证线程安全,防止数据竞争(Data Race)。C++11 引入了 std::mutexstd::unique_lockstd::lock_guardstd::shared_mutexstd::condition_variable 等,提供了更高效、更安全的同步机制。


📌 1. 互斥锁(std::mutex

std::mutex 基本用法

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;  // 互斥锁
int counter = 0;

void task() {
    for (int i = 0; i < 10000; i++) {
        mtx.lock();   // 加锁
        counter++;
        mtx.unlock(); // 解锁
    }
}

int main() {
    std::thread t1(task);
    std::thread t2(task);

    t1.join();
    t2.join();

    std::cout << "Final counter: " << counter << std::endl;
    return 0;
}

std::mutex 确保 counter++ 在多个线程下不会发生数据竞争。


📌 2. std::lock_guard(RAII 方式管理锁)

  • std::lock_guard<std::mutex> 自动管理 mutex,作用域结束时自动释放锁,避免 lock() 后忘记 unlock()
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void task() {
    for (int i = 0; i < 10000; i++) {
        std::lock_guard<std::mutex> lock(mtx); // 自动加锁 & 作用域结束自动解锁
    }
}

int main() {
    std::thread t1(task);
    std::thread t2(task);

    t1.join();
    t2.join();
    return 0;
}

RAII 方式,lock_guard 构造时加锁,析构时自动解锁,避免手动 unlock() 可能引发的死锁。


📌 3. std::unique_lock(支持 try_lock & defer_lock & unlock

  • lock_guard 更灵活,允许手动解锁、支持条件变量
  • 支持 try_lock()(尝试加锁)defer_lock(延迟加锁)
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void task() {
    std::unique_lock<std::mutex> lock(mtx); // ✅ 自动加锁
    // 临界区代码
    lock.unlock();  // ✅ 允许手动解锁
}

int main() {
    std::thread t1(task);
    std::thread t2(task);

    t1.join();
    t2.join();
    return 0;
}

📌 支持 try_lock()

if (lock.try_lock()) {
    std::cout << "Lock acquired!\n";
} else {
    std::cout << "Lock failed!\n";
}

📌 支持 defer_lock(延迟加锁)

std::unique_lock<std::mutex> lock(mtx, std::defer_lock);
lock.lock(); // 需要时再手动加锁

unique_lock 适用于需要手动解锁,或者与 std::condition_variable 结合的情况。


📌 4. std::shared_mutex(读写锁,提高并发性能)

  • 允许多个线程同时读取(shared_lock),但写入必须互斥(unique_lock
  • 适用于“读多写少”的场景,如缓存、数据库索引等
#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex rwlock;
int data = 0;

void reader() {
    std::shared_lock<std::shared_mutex> lock(rwlock);
    std::cout << "Reading data: " << data << std::endl;
}

void writer() {
    std::unique_lock<std::shared_mutex> lock(rwlock);
    data++;
    std::cout << "Writing data: " << data << std::endl;
}

int main() {
    std::thread t1(reader);
    std::thread t2(writer);
    std::thread t3(reader);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

多个 reader() 线程可以同时执行,而 writer() 线程必须独占访问,提高并发效率。


📌 5. std::condition_variable(线程间通知机制)

  • 用于线程间同步,A 线程等待 B 线程的信号
  • 适用于生产者-消费者模型

📌 示例

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [] { return ready; }); // 等待信号
    std::cout << "Worker received signal!\n";
}

void sender() {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lock(mtx);
    ready = true;
    cv.notify_one(); // 发送信号
}

int main() {
    std::thread t1(worker);
    std::thread t2(sender);

    t1.join();
    t2.join();
    return 0;
}

cv.wait(lock, [] { return ready; }) 确保线程 B 一定能收到信号,而不会丢失。


📌 6. std::atomic(无锁编程,适用于高并发)

  • std::atomic<T> 提供无锁线程安全操作,避免锁的开销,提高性能

📌 示例

#include <iostream>
#include <thread>
#include <atomic>

std::atomic<int> counter(0);

void task() {
    for (int i = 0; i < 10000; i++) {
        counter.fetch_add(1, std::memory_order_relaxed); // ✅ 原子操作
    }
}

int main() {
    std::thread t1(task);
    std::thread t2(task);

    t1.join();
    t2.join();

    std::cout << "Final counter: " << counter << std::endl;
    return 0;
}

std::atomic<int> 避免锁竞争,适用于高性能场景,如计数器、标志位。


📌 7. C++ 锁 API 对比

API作用是否手动解锁适用场景
std::mutex互斥锁✅ 需要手动 unlock()基本线程同步
std::lock_guard自动管理互斥锁❌ 作用域结束自动释放RAII 方式管理锁
std::unique_lock更灵活的互斥锁✅ 允许 unlock()需要 try_lock()defer_lock 的情况
std::shared_mutex读写锁✅ 需要手动 unlock()读多写少的场景
std::condition_variable线程间同步❌ 由 wait() 控制生产者-消费者模型
std::atomic无锁同步❌ 无需手动管理适用于高并发场景

📌 8. 总结

std::mutex 适用于基本线程同步,但需要手动 lock/unlock
std::lock_guardstd::unique_lock 避免手动 unlock(),防止死锁。
std::shared_mutex 适用于读多写少场景,提高并发性能。
std::condition_variable 适用于线程间通知,避免信号丢失。
std::atomic 适用于高性能无锁编程,减少锁竞争。

🚀 掌握这些 C++ 锁 API,将让你在多线程编程中更高效、安全地管理并发!🔥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值