linux 互斥机制

linux 互斥机制四种方式:中断屏蔽、原子操作、自旋锁、信号量

1. 必须先了解的基本概念

1.1 临界区

一段代码,在程序中多次被执行,每次执行的过程,我们称之为代码的执行路径。
当不只一个,及两个或以上代码路径要竞争一个共同的资源的时候,该代码段就是临界区。
那么在有一个线 程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。

1.2 互斥机制

访问共享资源的代码叫做临界区。当共享资源被多个线程访问,但是共享资源又不能被同时访问。
所以呢,临界区需要某种互斥机制来加以保护,确保共享资源被互斥访问。

1.3 用户空间和内核空间

出于安全考虑,linux系统 分为内核态和用户态,分别运行在内核空间和用户空间。
内核态: 程序可以执行特权指令,操作系统本身也在其中运行。
用户态:
1、 不允许直接访问操作系统的核心数据、设备等关键资源。
2、 先通过系统调用或者中断进入内核态才可以访问。
3、 当系统调用或中断返回时,重新回到用户空间运行。

2. Linux 的互斥机制

在这里插入图片描述
2.1 中断屏蔽

1.中断是一个完全异步的事件,它的发生与正在运行的进程没有任何关系,它没有进程上下文切换。
CPU具备屏蔽中断和打开中断的功能,这项功能可以保证正在执行的内核执行路径不被中断处理程序抢占,防止竞态的产生。
2.但是,内核的正常运行依赖于中断机制。在屏蔽中断期间,任何中断都无法得到处理,而必须等待屏蔽解除。因此长时间屏蔽中断对内核的运行起到很大的影响,其后果可能导致数据丢失,甚至系统崩溃。
3. 实际情况是:在中断服务全过程屏蔽中断会丢失中断;如果开中断,又容易引起互斥问题。
4.为了解决这个问题,Linux 把中断分为顶半部TH(Top Half)和底半部BH(Bottom Half)。
TH 屏蔽中断,执行一些少量的关键性动作;BH 可以开中断,允许中断延迟执行。

2.2 原子操作

所谓原子操作,就是“不可中断的一个或一系列操作”。
原子操作,就是不能被更高等级中断抢夺优先的操作。你既然提这个问题,我就说深一点。由于操作系统大部分时间处于开中断状态,所以,一个程序在执行的时候可能被优先级更高的线程中断。而有些操作是不能被中断的,不然会出现无法还原的后果,这时候,这些操作就需要原子操作。就是不能被中断的操作。

2.3 自旋锁
是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。
事实上,自旋锁的初衷是:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁被持有的时间不应该过长。如果需要长时间锁定的话, 最好使用信号量。
(1)自旋锁不能递归
(2)自旋锁可以用在中断上下文(信号量不可以,因为可能睡眠),但是在中断上下文中获取自旋锁之前要先禁用本地中断,中断是不参与系统调度的
(3)自旋锁的核心要求是:拥有自旋锁的代码必须不能睡眠,要一直持有CPU直到释放自旋锁

2.4 信号量
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程 最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。

3. 总结:

打一个比喻: 可以理解为大家在一套房子里合租,共用一个厕所。 厕所就是共享资源,去上厕所的行为被称作代码路径。

3.1 中断屏蔽:

就是,有一个人想要用厕所,但是呢他在上厕所前在门口贴上纸条说厕所坏了,如果他很快出来倒还不要紧,但是如果他要上很长时间,那一起住的其他人可能就要憋爆了。所以中断屏蔽最开始不会被用于处理需要耗时很长的操作。但是大家想,这样不是个解决办法啊,我有时候确实要拉很长时间怎么办呢。
于是发明了顶半部TH和底半部BH,TH用于执行少量的关键性的动作,BH用于处理中断中耗时的部分。
可以理解为,某人A特别特别想上厕所的时候,就进入TH(可以看作一个状态),此时A去应个急,拉一点点,让肚子不那么疼,此时A是不可以被打断的。如果没人用厕所他就直接慢条斯理的开始拉了(BH)。但是他这个BH状态是可以打断的,如果此时来个人B 非常非常急,B进入TH说,我受不了啦要憋死啦,A就会暂停自己的状态(保护现场)让B进来拉一会(TH),等B拉了一点点,让肚子不那么疼了就出去。此时 A继续(恢复现场)。等A 的BH部分完全结束后B再执行B的BH部分。

3.2原子操作:

很好理解,就是大家每次上厕所都用时非常短,短到什么程度呢,只要一条汇编指令的时间。当然拉的量也非常少(只改变一个整型或者是位)。所以就不存在抢厕所的问题了。

3.3自旋锁:

顾名思义,给这个厕所上把锁,只有拥有这个锁钥匙的人A才能进厕所。进去后把锁锁上,外面的人B急得团团转(自旋),出来后把锁释放,在门口等着的B拿了钥匙赶紧开了锁进去了。但是缺点就是,B在外面团团转,没有功夫去做别的事情,所以一旦 A 上厕所的时间很长,B就浪费了很长时间在自旋上。对系统的性能有所影响。

3.4信号量:

信号量就是,我们的房子有 N 个厕所,N 不为 1, 且 N 为有限个,上厕所的人是有限的。即共享这一块资源的进程是有限个数的。这时候我们就可以在厕所门口挂上 N 吧钥匙,拿到钥匙的就可以进去,钥匙架空了,其他进程就只能在门口等待出来的人还钥匙。

参考文献:https://blog.csdn.net/dearsq/article/details/52175401
参考文献:https://www.cnblogs.com/linux-37ge/p/10208369.html

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值