Linux 锁机制(5)之互斥,读写,信号量和自旋锁总结比较

锁的相关文章
多线程(4)什么是锁?锁机制,死锁等说明
https://blog.csdn.net/lqy971966/article/details/104527787

Linux 锁机制(1)之互斥量 mutex
https://blog.csdn.net/lqy971966/article/details/119108670

Linux 锁机制(2)之读写锁 rwlock_t
https://blog.csdn.net/lqy971966/article/details/103541567

Linux 锁机制(3)之自旋锁
https://blog.csdn.net/lqy971966/article/details/103541614

Linux 锁机制(4)之信号量
https://blog.csdn.net/lqy971966/article/details/119326689

1. 互斥,读写,信号量和自旋锁总结比较

1.1 选择锁的几个参考:

1.1.1 首选互斥锁

当无法判断锁住的代码会执行多久时,应该首选互斥锁
互斥锁能够满足各类功能性要求,特别是被锁住的代码执行时间不可控时,它通过内核执行线程切换及时释放了资源,但它的性能消耗最大。

注意:
信号量和互斥量有些类似,记住

  1. 独占情况下使用互斥量
  2. 流程则使用信号量;

1.1.2 执行时间短/临界区小,选择自旋锁

如果能够确定被锁住的代码取到锁后很快就能释放,应该使用更高效的自旋锁,它特别适合基于异步编程实现的高并发服务。

  1. 临界区要小(否则出现死等,浪费cpu)
  2. 可以在中断上下文执行
  3. 不允许睡眠(会出现死锁)

1.1.3 如果能区分出读写操作,读写锁就是第一选

它允许多个读线程同时持有读锁,提高了并发性。

读写锁的特性为:写独占,读共享;写锁优先级高。
非常适合于对数据结构读多写少的情况。

读写锁既可以使用互斥锁实现,也可以使用自旋锁实现,我们应根据场景来选择合适的实现

1.1.4 如果是流程上,则选择信号量

信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作,这是是流程上的概念。

比如: 有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类

而互斥量则纯粹是“锁住某一资源”的概念

1.2 互斥锁和自旋锁的比较

1.2.1 互斥锁和自旋锁的比较(成本,睡眠,中断)

锁类型 	成本(sizeof) 中断能否使用	加锁失败睡眠				
互斥锁	高(40字节)	 不可以			睡眠,线程会释放cpu给其他线程			
自旋锁	低(4字节)	 可以			不睡眠,线程会忙等待,直到它拿到锁

/* 自旋锁 */
typedef struct {
	unsigned long ulLock;
} spinlock_t;
spinlock_t //其本质上是一个整数值(对该数值的操作需要保证原子性),
			该数值表示spin lock是否可用。初始化的时候被设定为1

说明:
1.sizeof(mutex)=40 //centos7 测试结果
2.由于不睡眠,内核中的中断上下文中只能使用自旋锁
3.互斥锁的加锁成本更高,但它在加锁失败时会释放 CPU 给其他线程
成本大,并且性能比 spin 差;会膨胀;会休眠;但是可以切出去 做别的事

无论互斥锁、自旋锁还是读写锁,都属于悲观锁。

1.2.2 互斥体和自旋锁场景选择:

需求		建议的加锁方法
低开销加锁	优先使用自旋锁
短期锁定	优先使用自旋锁
长期加锁	优先使用互斥体
中断上下文中加锁	使用自旋锁
持有锁需要睡眠	使用互斥体

1.3 信号量和互斥锁的区别:

1.3.1 相同点:(会有上下文切换/睡眠)

信号量和互斥锁都会在获取锁失败情况下睡眠,会有上下文切换,线程会释放cpu给其他线程。

这点和自旋锁的区别。

1.3.2 不同点:(流程和锁住)

1.3.2.1 信号量不一定是锁定某一个资源,而是流程上的概念

信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作,这是是流程上的概念。

信号量不一定是锁定某一个资源,而是流程上的概念。
比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类

1.3.2.2 互斥量则纯粹是“锁住某一资源”的概念

互斥锁是用在多线程多任务互斥,在锁定期间内,其他线程无法对被保护的数据进行操作。

1.3.2.3 作用域

信号量: 进程间或线程间(linux仅线程间)
互斥锁: 线程间

1.3 互斥体和信号量场景选择:

只要满足互斥体的使用场景就尽量优先使用互斥体。

1.在有些情况下两者可以互换。

2.独占情况下使用互斥量
因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。

参考:
https://www.cnblogs.com/-wenli/p/13618667.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值