锁的基础概念(C++)

本文围绕C++中的锁展开,介绍了独占锁、共享锁、自旋锁、递归锁、悲观锁、乐观锁等不同类型锁的特点和使用场景。还对比了std::unique_lock<>和lock_guard的功能差异,指出Unique_lock更灵活但维护成本高,并给出了使用示例。

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

计算机软件层面存在许多工程概念,但他们的实现机制本质是一致的;在操作系统层面则是信号量和管程;

工程上对锁的一些概念,示例;

1:早版本的c++的stl库就提供了std::mutex(头文件<mutex>),称为独占锁,只能同时被一个线程占有;对独占锁,锁定两次会引发未定义行为;

RAII的意义在于在该类对象析构时,自动释放作用的对象,stl库中存在这种写法

2:共享锁(c++17),典型场景在读写环境使用;std::shared_mutex\std::sharedlock;(头文件<shared_mutex>)

多个线程可同时锁定shared_lock<typename t>lk(sharedMutex),通常对应着读取数据的操作,这个操作与unique_lock锁定了shared-mutex的动作互斥,通常对应修改数据的操作;这两者是互斥的;

dns缓存读写例子:

读写锁Dns缓存

3:自旋锁:如果有个线程,发现自旋锁被锁住了,区别独占锁,不会进入进程阻塞的队列等待,而是会不停的轮询自己,能不能占有该锁(busy-waiting);显然这个锁有效率和资源占用问题;linux的头文件有这个锁,(linux\spinlock);

4:递归锁;他的意义是:可以允许多次锁定,并增加计数;允许多次解锁减少计数,锁定解除的条件为,所有占用过该锁的线程,全部解锁;

悲观锁:每次读写都上锁再进行,总是假设有人在自己读写前之前会更改数据,因此效率堪忧,使用读写频繁的情况;

乐观锁:假设每次都没人改,先读写再说;一般会有一个版本号的记录,如果读写发现版本号不对,就锁住数据写入过程进行更改;git的push就是一种乐观锁;

最后讲一下std::unique_lock<>和lock_guard的功能差异;

Unique_lock更加灵活:第二个参数可以传入adopt_lock,以供让互斥元自己上锁;

也可以传入,std::defer_lock表示构造时未锁定,之后通过手动lock来控制上锁;

但更加笨重,传入的参数需要维护成本;

例如当我们需要比较两个经常被更改的数据是否一致时,可以通过unique锁暂时在构造时不锁定,在比较的上一行一起锁定;给个eg:

friend bool operator==(typename lhs& ,typename & rhs ){

if(lhs == rhs)

return true;

std::unique-lock<std::mutex>lock_a(lhs.value,std::defer_lock);

std::unique-lock<std::mutex>lock_b(rhs.value,std::defer_lock);

std::lock(lock_a,lock-b);

return lhs.value==rhs.value;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值