📌 C++ 锁机制(Lock API)详解
在 C++ 多线程编程中,锁(Lock)主要用于保证线程安全,防止数据竞争(Data Race)。C++11 引入了 std::mutex、std::unique_lock、std::lock_guard、std::shared_mutex、std::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_guard 和 std::unique_lock 避免手动 unlock(),防止死锁。
✅ std::shared_mutex 适用于读多写少场景,提高并发性能。
✅ std::condition_variable 适用于线程间通知,避免信号丢失。
✅ std::atomic 适用于高性能无锁编程,减少锁竞争。
🚀 掌握这些 C++ 锁 API,将让你在多线程编程中更高效、安全地管理并发!🔥
3053

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



