程序员笔记 (四十四)unique_lock


aihuafeng66t
克里斯蒂亚诺诺 2024-01-12 14:07:59 64353 赞同 0 反对 0
分类: 资源 标签: 运维
程序员笔记 (四十四)unique_lock

(一)unique_lock

std::unique_lock为锁管理模板类,是对通用mutex的封装。std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作,即在unique_lock对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而unique_lock的生命周期结束之后,它所管理的锁对象会被解锁。unique_lock具有lock_guard的所有功能,而且更为灵活。虽然二者的对象都不能复制,但是unique_lock可以移动(movable),因此用unique_lock管理互斥对象,可以作为函数的返回值,也可以放到STL的容器中。

std::unique_lock还支持同时锁定多个mutex,这避免了多道加锁时的资源”死锁”问题。在使用std::condition_variable时需要使用std::unique_lock而不应该使用std::lock_guard。
std::unique_lock类成员函数介绍:
(1). unique_lock构造函数:禁止拷贝构造,允许移动构造;
(2). operator =:赋值操作符,允许移动赋值,禁止拷贝赋值;
(3). operator bool:返回当前std::unique_lock对象是否获得了锁;
(4). lock函数:调用所管理的mutex对象的lock函数;
(5). try_lock函数:调用所管理的mutex对象的try_lock函数;
(6).try_lock_for函数:调用所管理的mutex对象的try_lock_for函数;
(7).try_lock_until函数:调用所管理的mutex对象的try_lock_until函数;
(8). unlock函数:调用所管理的mutex对象的unlock函数;
(9). release函数:返回所管理的mutex对象的指针,并释放所有权,但不改变mutex对象的状态;
(10). owns_lock函数:返回当前std::unique_lock对象是否获得了锁;
(11). mutex函数:返回当前std::unique_lock对象所管理的mutex对象的指针;
(12). swap函数:交换两个unique_lock对象。

(二)

std::unique_lock比std::lock_guard更灵活,这种灵活性主要体现在以下几点:

lock_guard在构造时或者构造前(std::adopt_lock)就已经获取互斥锁,并且在作用域内保持获取锁的状态,直到作用域结束;而unique_lock在构造时或者构造后(std::defer_lock)获取锁,在作用域范围内可以手动获取锁和释放锁,作用域结束时如果已经获取锁则自动释放锁。

lock_guard锁的持有只能在lock_guard对象的作用域范围内,作用域范围之外锁被释放,而unique_lock对象支持移动操作,可以将unique_lock对象通过函数返回值返回,这样锁就转移到外部unique_lock对象中,延长锁的持有时间。


int n;std::mutex some_mutex;
void prepare_data(){ cout << n++ << endl;}
void do_something(){ cout << n++ << endl;}
std::unique_lock<std::mutex> get_lock(){ std::unique_lock<std::mutex> lk(some_mutex);//与lock_guard相同,构造时获取锁 cout << "owns_lock? " << lk.owns_lock() << endl;//1 prepare_data(); return lk;}
int main(){ //unique_lock基本使用 std::mutex mutex2; std::unique_lock<std::mutex> lock2(mutex2, std::defer_lock);//告诉构造函数暂不获取锁 cout << "owns_lock? " << lock2.owns_lock() << endl;//0 lock2.lock();//手动获取锁 std::cout << "owns_lock? " << lock2.owns_lock() << endl;//1 lock2.unlock();//手动解锁 cout << "owns_lock? " << lock2.owns_lock() << endl;//0 //锁所有权转移到函数外部 std::unique_lock<std::mutex> lk(get_lock());// do_something();}//析构//lock2未获取锁mutex2,因此不会调用unlock//lk对象持有锁some_mutex,调用unlock


如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
克里斯蒂亚诺诺L1
粉丝 0 资源 831 + 关注 私信
最近热门资源
银河麒麟桌面操作系统V10SP1-2403-update1版本中,通过“麒麟管家-设备管理-硬件信息-硬盘”查看硬盘类型时,显示的是HDD(机械硬盘),而实际上该笔记本的硬盘类型为SSD  40
统信uos安装mysql的实例参考  31
分享解决宏碁电脑关机时自动重启的方法  30
在银河麒麟高级服务器操作系统V10SP3中,需要将默认shell类型修改为csh。  29
分享如何解决报错:归档 xxx.deb 对成员 control.tar.zst 使用了未知的压缩,放弃操作  28
统信uosboot区分未挂载导致更新备份失败  27
格之格打印机dp3300系列国产系统uos打印机驱动选择  25
以openkylin为例编译安装内核  23
最近下载排行榜
银河麒麟桌面操作系统V10SP1-2403-update1版本中,通过“麒麟管家-设备管理-硬件信息-硬盘”查看硬盘类型时,显示的是HDD(机械硬盘),而实际上该笔记本的硬盘类型为SSD 0
统信uos安装mysql的实例参考 0
分享解决宏碁电脑关机时自动重启的方法 0
在银河麒麟高级服务器操作系统V10SP3中,需要将默认shell类型修改为csh。 0
分享如何解决报错:归档 xxx.deb 对成员 control.tar.zst 使用了未知的压缩,放弃操作 0
统信uosboot区分未挂载导致更新备份失败 0
格之格打印机dp3300系列国产系统uos打印机驱动选择 0
以openkylin为例编译安装内核 0
作者收入月榜
1

prtyaa 收益400.53元

2

zlj141319 收益237.46元

3

哆啦漫漫喵 收益231.42元

4

IT-feng 收益219.71元

5

1843880570 收益214.2元

6

风晓 收益208.24元

7

777 收益173.07元

8

Fhawking 收益106.6元

9

信创来了 收益106.03元

10

克里斯蒂亚诺诺 收益91.08元

请使用微信扫码

添加我为好友,拉您入交流群!

请使用微信扫一扫!