进程互斥的四种软件实现方法
这个小节我们会介绍另外的三种进程互斥的硬件实现方法
那么 这个小节的学习过程当中 大家需要注意理解各个方法的原理 并且要稍微的了解各个方法
有什么有缺点 那么首先来看第一种中断屏蔽方法 其中断屏蔽这种方式咱们在之前介绍原语的时候
也介绍过 他 无非就是使用开和关中断这两个指令来实现
不可被中断中断屏蔽这件事情 那么原语不可被中断的这个特性其实也是用这样一组指令来实现的
在一个进程访问临界区之前 他会执行一个关中断指令
也就意味着执行了关中断之后 这个进程就不可能在被中断 也就意味着不可能会再发生这个进程切换的事情
一直到这进程访问完临界区执行开中断指令之后 才有可能会有别的进程
被切换上处理机运行并访问这个临界区 所以这种方式很明显
它的优点就是实现起来很简单高效 并且这个逻辑其实很清晰
然后缺点呢就是它不适用于多处理机的这种系统 因为
关中断指令指对执行关中断指令的那个处理机有用
所以 如果此时处理机a执行了关中断指令 那么就意味着在这个处理机上面的进程不会被切换
那么 这个进程就可以顺利的访问临界区 但是对于另一个处理机处理机b来说
他其实还是会正常的切换进程 如果说此时另外的那个处理机上运行的进程
也需要访问这个临界区 也用这种方式的话 那么也有可能会发生两个处理机上的两个进程同时对临界区进行访问的情况
所以 这是中断屏蔽方法不适用于多处理机的原因
另外一个缺点呢就是关中断和开中断这两个指令 它的权限特别大 它属于特权指令 需要在内核太下才能运行 因此
这种方式只适用于操作系统内核进程 不适用于用户进程 只有操作系统内核进程才有权限执行这两个指令
所以这是中断屏蔽方法 那么第二个硬件实现方式是TestAndSet这样一个指令
这个指令可以简称为ts 指令就是 TestAndSetLock 然后有的地方有的书上也可 也会把它称为 TestAndSetLock
也就tsl指令 所以在咱们的408真题当中也出现过tsl这样的
一个表述方式 所以这两个名称大家都需要注意一下 那这个指令其实是用
硬件来实现的 在执行的过程当中是不允许被中断 只能一气呵成 额 这个是用c语言描述的 TestAndSetLock 这个指令的一个逻辑
需要强调的是 这个只是为了表示一个逻辑 让大家理解他在背后做了一些什么事情
但这些事情其实都是由硬件来完成的 并且它不可以被中断 系统会为临界区设置一个共享变量 布尔行的变量lock
lock是用来表示当前这个临界区是否已经被枷锁是否已经被上锁
如果他为true的话 就表示已经有某一个进程 表示要对这个临界区上锁 如果为false的话 就是不上锁
那么他TestAndSet这个指令 他在背后做的事情就是
首先 它会用一个叫做od的一个也是布尔行的变量
用来记录以前lock他的值到底是多少 也就是用来记录之前这个临界区是否已经被上锁了
然后 无论这个临界区是否被上锁 他在记录下来这个值之后 一定会让这个临界区进入一个枷锁 一个上锁的状态
也就是把lock这个值设为true之后再用某种方式返回
这个值 那么 在实际使用tsl实现互斥的过程当中 就是用这样的方式来实现的
在while这个循环当中 会不断的执行TestAndSet这个指令
如果说lock本来就是true 也就是说 以前这个临界区就是被上锁的 那么他返回来的old这个值也会为true
那么while这个循环就会一直循环下去 循环条件会一直满足 一直到luck这个值
被当前访问临界区的那个进程在退出区改成了false 所以就会变成
TestAndSet这个返回来的old这个值变为了false 于是之前一直被卡在这儿的那个进程就可以跳出这个循环 然后
正式的开始访问临界区的代码段 一直到访问结束之后再把自己上的锁给解除
所以这是TestAndSet这个指令的一个实现的一个逻辑 这个地方虽然用了return 但实际硬件执行的过程当中其实就是把lock这个值放到了某一个物理寄存器里
然后再把log这个值覆盖为true 是做了这样一个事情 所以
刚才咱们已经分析了lock为false和lock为true的情况 那这个算法和之前咱们介绍的软件实现的方法相比
其实在那个双标志先检查当中 导致最后出问题的原因是
在进入区当中进行上锁和检查这两个操作并不是一气呵成的
但是如果说用硬件的卷tsl这个指令来执行的话 那么就可以保证检查和上锁这两个事情其实是一气呵成的
一边把他上锁一边进行检查 把以前的那个值给返回回来
所以这是这是他能解决问题的一个原因 这种方式的优点呢 就是实现起来很简单 其实如果用如果有这样一个指令的话 那我们的代码不会特别复杂 可以很简洁
不需要像软件的实现方法那样计算推算是否会有异步带来的一些逻辑漏洞
所以这种方式其实是比起软件解决方法来说是要好的多的 并且它也适用于多处理机环境 当然为什么适用于多处以及环境 这个有兴趣的同学大家可以去傻查一下 涉及到总线相关的一些
一些一些特性 但这个方法也有一个缺点 就是它不满足让权等待的原则
通过刚才的分析 我们知道 当这个lock此时是被上锁的情况下
那么 此时想要再进入临界区的另外一个进程 它会一直在这个while循环里被卡住 一直不断的执行tsl这个指令 所以即使暂时没有办法进入临界区 但是它也会一直占用着cpu 然后执行这个指令
从而导致这种满本的这种现象随着它的一个缺点 但最后我们再来介绍swap指令
那大家也需要注意一下 另外这两个名称在考试中如果不小心遇到的话 也需要能够知道 他说的就是swap指令
这个指令和刚才tsl一样 它也是用硬件实现 并且中间是不允许被中断的
那么 swap指令做的事情其实就是交换了两个变量的值 把a的值换到了b 这把b的值换到a 这这个逻辑并不复杂
那么 它在具体的使用当中实现互斥 是这样实现的 其实表面上看起来swap和之前tsl是有很大不同 但是
逻辑上来看 他们所做的事情其实也差不多 也就是刚开始他会用一个old这样的一个变量
来记录以前lock这个值到底是是true还是
lock这个值和tsl里面一样 就是用来表示当前临界区是否已经被上锁
那么 swap这个指令对lock好和old这两个变量进行交换 之后
那么以前的lock的值会放到old里面 然后old本来是true的 那么他这个处这个值又会被设置到lock 这所以其实他做的和tsl指令可以说在逻辑上看是一模一样的 那么
在执行了这个指令之后 会例行检查以前lock这个值是否为true
如果说old这个值为true的话 那么就说明在之前这个临界区就已经被上锁了 那么这个循环会一直循环下去
一直到old为false 那么说明之前这个临界区是没有被上锁的状态 那么就会跳出这个循环 然后可以顺利的
进入临界区 访问这些代码段 当然swap指令和tsl指令在硬件层次可能实现的方式会不太一样 但是我们可以看到逻辑上看 他们俩做的事情其实并没有太大的区别
所以他们的优点和缺点也可以说是一样的 就是实现简单 但是也适合于多处理机的环境
不过 同样和tsl指令一样 都不满足让权等待的原则 如果说此时暂时不能进临界区的话 他可能一直被卡在这个循环 这占用处理机 然后不断的循环检查 进入满等的状态
所以这就是这个小节的全部内容 我们介绍了三种硬件进程互斥的硬件实现方式 其中tsl和sw这两种指令在逻辑上其实就是做了这样几个事情
大家再结合这个图再来回忆分析一下 那么对于中断屏蔽这种方法来说 它只适用于单处理机系统
并且只能由操作系统内核进程来使用开关中断这两个特权指令
好的 那么以上就是这个小节的全部内容
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习