143-再谈mtx和lock_guard和unique_lock

本文详细介绍了C++中三种线程同步机制:mutex、lock_guard和unique_lock。lock_guard确保在作用域内自动加锁和解锁,适用于简单同步场景,而unique_lock除了自动管理锁的生命周期外,还支持右值引用,可用于函数参数传递。此外,文章提到了条件变量cv.wait使用unique_lock的原因,并解释了notify_all函数在多线程通信中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、mutex

在这里插入图片描述

  • 不安全,因为代码之间可能由于逻辑走掉了,代码发生异常了,造成锁没有释放掉,成死锁

2、lock_guard

在这里插入图片描述

  • 利用的是智能指针的概念。
  • 在它的构造函数里面可以主动的获取这把锁lock。
  • 当这个对象出作用域,自动调用析构函数,析构函数中有释放锁的操作unlock。
  • 它把左值引用的拷贝构造函数和赋值函数都删除掉了。

不可能用在函数参数传递或者返回过程中,因为要用到拷贝构造函数和赋值函数,只能用在简单的加锁解锁临界区代码段的互斥操作中。
只能用在简单的加锁解锁的临界区代码中;
在这里插入图片描述

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()函数。

lock_gard源码:
在这里插入图片描述
unique_lock源码:
在这里插入图片描述
在这里插入图片描述

5、notify_all

	/*
	通知在cv上等待的线程,条件成立了,起来干活了!
	其它在cv上等待的线程,收到通知,
	从等待状态 =》到阻塞状态(不能直接运行) 
	=》只有当前线程释放锁了,其他线程才能获取互斥锁了 =》线程继续往下执行
	*/
	cv.notify_all();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liufeng2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值