考研408《操作系统》复习笔记,第二章《2.4 同步互斥》
一、回顾知识点
这一章第一节说过,进程具有【异步性】
- 【异步】:就是各进程并发交替的运行,宏观上同时运行,不会一个等另一个执行完才运行;各个进程是按未知的速度前进的。
- 【同步】:必须等上一个进程全部执行完了,才能到下一个进程执行
二、同步互斥概念
【临界资源】
;
;
要注意一定要遵守【临界区资源互斥准则】:
那么我们结合前面【同步】的概念,同步就是限制一个进程先执行完再到另一个进程,不可以穿插,那不正好适用于【临界资源】吗,所以【对临界资源访问】——————要采取【同步互斥机制】
三、互斥具体实现
1、软件实现
那就当成我们写得代码就行了,我们在逻辑上规定好访问的进程对临界资源访问的流程
简单来说,逻辑就是:
- 【上锁,不让别的进程用】—>
- 【该进程进入临界区,访问临界资源】—>
- 【解锁,让别的进程也能用】—>
- 【做其他处理(可有可无,非考试重点)】
【具体三大算法】
1)单标志法
要记住:
- 可能违背【空闲让进原则】
- 必须得2个进程都有意愿使用资源,并交替运行
;
;
2)双标志先检查法
要记住:
- 【判断是否可访问的依据是:对方用不用,用就谦让】
- 可能违背【忙则等待原则】
;
;
3)双标志后检查法
要记住:
- 先【更改自己的flag值为“true”】,再【判断对方flag值,对方用就谦让】
- 可能【互相谦让,一起循环等待饿死】
;
;
4)Peterson算法(无敌了)
要记住:
- 结合【单标志法】+【双标志后检查法】
- 依旧先【更改自己的flag值、turn公共值】,再【判断对方flag && 公共turn】
- 解决【饥饿问题】!!!
- 但也违背了【让权等待】!!!
- (因为有while循环,如果你没有资格进入临界区,你只会一直在while循环,也不能修改flag值让出位置给别的进程)
- (但其实可以发现前面几个算法都有while循环,其实都违背了【让权等待】,只不过它不是最主要的特点)
;
;
【总结】
2、硬件实现
【前提说明】
原理就是:只用一句【机器指令】,完成一系列不可中断的原子操作,来实现进程上锁
;
这里需要特别说明:
- 1、【机器指令】是一整条直接执行完毕,具有【原语性】不可以被中断
- 而下面我们写得代码是按人的逻辑来解释:
- 这个机器指令做了哪些步骤,而并非真的按代码一句一句执行
- 2、【软件实现】的各个进程代码可以并发穿插执行,但是【硬件机器指令】不行
1)关中断指令
老朋友,再熟悉不过了,【关中断】就是一种【原语指令】,屏蔽掉中断而让当前进程一直执行,其他进程再怎么发I/O请求而触发中断,人家都闭门造车听不见,直到【开中断指令】,没啥好说的
2)TS指令
全名【Test and Set指令】或【TSL指令】
结合进程的“软件实现”代码,整体流程如下:
【核心思想】就是:机器指令里【记录锁状态】的同时、【保持上锁】
- 这样的好处就是:
- 如果被其他进程上锁了,既能检测出被上锁,又能保持上锁状态不变
- 如果资源是空闲解锁状态,那马上检测到、并上锁,然后自己使用该资源
3)Swap指令
又称【exchange指令】、【EXCH指令】,顾名思义就是【交换】
交换什么:【资源锁的状态lock】和【进程的key: 记录lock旧值】
- 注意:
- 【lock】是全局变量,资源的上锁、解锁状态,任何进程都可以检测到
- 【key】是局部变量,只在一个进程内有效,进程A的key和进程B的key值不一样
结合进程的“软件实现”代码,整体流程如下:
【总结】
3、互斥锁(Mutex)
1)概念
前面我们讲了【软件互斥逻辑】和【硬件互斥指令】
那么我们在写代码的时候也知道,想要使用重复的某一功能代码,我们通常不会选择一大段代码重新复制粘贴好几次、或者重写好几次;也不会希望直接接触底层硬件逻辑,编写操作系统的指令代码
所以就有了【互斥锁Mutex】,可以理解为把【软件互斥逻辑】和【硬件互斥指令】封装起来的【接口】,我们无需关心里面的代码逻辑、硬件实现,只需要在进入临界区的时候用上【互斥锁上锁】,离开临界区的时候【解开互斥锁】