lock_guard的使用
std::lock_guard 是 C++11 引入的一个模板类,位于 <mutex> 头文件中,用于实现 RAII(Resource Acquisition Is Initialization)模式的锁管理,确保锁的自动获取与释放,即使在异常情况下也能正确释放锁,防止死锁。
基本用法如下:
std::mutex mtx; // 创建一个 mutex
void func() {
std::lock_guard<std::mutex> lock(mtx); // 在这里自动获取锁
// ... 执行临界区代码 ...
// 锁会在 lock_guard 实例离开作用域时自动释放
}
unique_lock的使用
std::unique_lock具有lock_guard的功能,但同时unique_lock可以使用mutex的接口lock和unlock来主动加锁和释放锁,而lock_guard是不支持的。并且,unique_lock还可以配合condition_variable来使用。使用方式如下:
std::mutex mtx;
std::condition_variable cv;
std::queue<int> q;
bool stop = false;
void func()
{
while (!stop) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [&stop, &q]{ return stop || !q.empty(); });
if (stop) break;
// do something
lock.unlock(); // 也可以不调用,让其自动释放
}
}
//....
cv.notify_one(); // 在某处向队列中添加数据时,会唤醒一个阻塞的线程。
这是一个典型的使用互斥锁加条件变量的方式,在调用wait接口时,如果不满足返回条件,则线程会阻塞住,并释放锁。
两者的区别
- unique_lock支持直接调用mutex的lock和unlock接口,而lock_guard不支持;
- unique_lock可以和条件变量配合使用,lock_guard不支持;
- unique_lock可以移动mutex的所有权,lock_guard不支持;
- lock_guard比unique_lock要轻量级,如果只是简单的使用智能的锁管理模式,使用前者更佳。