再谈mtx和lock_guard和unique_lock
大约 3 分钟
再谈mtx和lock_guard和unique_lock
1、mutex
std::mutex mtx;
int main() {
mtx.lock();
mtx.unlock();
return 0;
}
- ,因为代码之间可能由于逻辑走掉了,代码发生异常了,造成锁没有释放掉,成
2、lock_guard

- 利用的是智能指针的概念。
- 在它的构造函数里面可以主动的获取这把锁lock。
- 当这个对象出作用域,自动调用析构函数,析构函数中有释放锁的操作unlock。
- 它把。
或者中,因为要用到拷贝构造函数和赋值函数,。
std::mutex mtx;
int main() {
//只能用在简单的加锁解锁的临界区代码中;
guard_lock<std::mutex> guard(mtx);
//mtx.lock();
//mtx.unlock();
return 0;
}
3、unique_lock
- 利用的是智能指针的概念。
- 在它的构造函数里面可以主动的获取这把锁lock。
- 当这个对象出作用域,自动调用析构函数,析构函数中有释放锁的操作unlock。



它把左值引用的拷贝构造函数和赋值函数都删除掉了。


它还提供了一对lock和unlock方法。

std::mutex mtx;//底层是pthread_mutex_t
std::condition_variable cv;//底层是pthread_condition_t
unique_lock<std::mutex> lck(mtx);
cv.wait(lck);
//=> #1.使当前线程进入等待状态 #2.lck.unlock可以把mtx给释放掉
注意: 条件变量cv.wait里面传的是unique_lock,也只能传unique_lock,因为lock_gard将拷贝构造和赋值重载都delete了(实参到形参是一个拷贝构造的过程,传不进来)
4、lock_gard和unique_lock对比
- lock_gard和unique_lock可以看成unique_ptr和scope_ptr之间的关系;
- 因为要用到拷贝构造函数和赋值函数,或者中,。
- lock_gard和unique_lock做的事情是一样的,都是在构造函数中国自动执行mutex的lock()函数,在析构函数中自动执行mutex的unlock()函数。
5、notify_all
/*
通知在cv上等待的线程,条件成立了,起来干活了!
其它在cv上等待的线程,收到通知,
从等待状态 =》到阻塞状态(不能直接运行)
=》只有当前线程释放锁了,其他线程才能获取互斥锁了 =》线程继续往下执行
*/
cv.notify_all();