文章目录
一.概念
- 临界资源:在一个时间段内只允许一个进程访问的资源叫做临界资源
- 进程互斥:当一个进程在访问临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能访问该临界资源
二.进程互斥的组成部分
- 进入区:用于检查是否可以进入临界区。如果可以进入,则应设置正在访问临界资源的标志(类似于给临界资源上锁),以阻止其他进程访问临界资源
- 临界区:访问临界资源的那段代码
- 退出区:负责解除正在访问临界资源的标志(也就是给临界资源解锁)
- 剩余区:做其他处理
三.进程互斥的原则
- 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区
- 忙则等待:当一个进程正在访问临界区时,其他想要访问临界区的进程必须等待
- 有限等待:对请求访问临界区的进程,应保证能在有限时间内进入临界区
- 让权等待:当进程不能进入临界区时,应立即释放处理机
四.进程互斥的软件实现方法
1.单标志法
算法思想:
一个进程访问完临界区后,会将访问临界区的权限交给另一个进程。即进程访问临界区的权限是另一个进程赋予的。
- 在开始时,turn的值为0,也就是说此时允许p0进程访问临界区
- 如果此时p1进程要访问临界区,则p1进程会一直卡在代码5处,直到时间片用完,发生进程调度,切换p0进程上处理机运行
- 如果此时p1进程要访问临界区,由于turn=0,会跳过代码1开始执行2,也就是进入了临界区,在访问完临界区后,p0进程会将turn的值改为1,那么此时p1进程就可以访问临界区
- 如果在p0在访问临界区的过程中发生了进程调度,切换到了p1,由于p0还没有结束对临界区的访问,因此此时的turn值仍然为0,所以p1是不能访问临界区的
- 该算法存在的问题是:由于turn值的修改是发生在访问完临界区之后的,假设此时turn值为0,允许p0进程访问临界区,如果p0一直不开始访问临界区,那么turn值是不会发生修改的,这就会导致临界区明明是空闲的,但是p1却不能进行访问。违背了“空闲让进”原则。
2.双标志先检查法
算法思想:
设置一个布尔型数组flag[],数组中的各个元素用来标记各进程想要进入临界区的意愿(比如flag[0]=true则表示p0进程此时想要进入临界区)。每个进程在进入临界区前会先检查此时有没有别的进程想进入临界区,如果没有,则把自己的flag[i]标志改为true(也就是给临界区上锁),然后开始访问临界区。(先检查后上锁)
- 如果此时p0进程想要访问临界区,它会先检查有没有别的进程想要访问临界区,如果发现p1进程也想要访问临界区,那么代码会一直卡在代码1处,一直循环等待
- 如果发现此时p1进程不想访问临界区,那么会跳过代码1,执行代码2,也就是修改自己的意愿,表示自己想要进入临界区,然后执行代码3开始访问临界区,在访问完临界区以后,执行代码4修改自己的意愿,表示自己此时已经不想进入临界区了。
- 该算法存在的问题是:如果在p0执行完代码1发现p1并不想访问临界区,但此时正好发生了进程切换,切换到了p1进程,开始执行代码5,由于p0还没有来得及修改自己想要进入临界区的意愿,那么p1在执行代码5时会认为p0此时不想访问临界区,如果此时又切换到了p0,那么p0会开始执行代码2,表示自己想要进入代码区,如果此时又切换到了p1,则p1会执行代码6,p1也表示自己想要进入临界区,那么就会出现两个进程同时访问临界区。违背了“忙则等待”的原则。
- 出现问题的原因是:检查是否有别的进程想要进入临界区和修改自己想进入临界区的意愿这两个操作不是一气呵成的,中间会因为进程切换产生问题。
3.双标志后检查法
算法思想:与双标志先检查法类似,但是改为先上锁后检查
- 当p0想要进入临界区时,会先修改自己的意愿,表示自己想进入临界区,然后再检查是否有其他进程也想要进入临界区
- 如果发现p1想进入临界区,则卡在代码2处循环等待
- 如果发现p1不想进入临界区,则开始访问临界区,并且在访问完临界区后,修改自己的意愿,表示自己不想访问临界区了
- 该算法存在的问题是:如果p0刚刚执行完代码1,表示自己想要进入临界区,此时发生了进程切换,切换到了p1,开始执行代码5,那么p1也表示自己想要访问临界区,此时又切换到了p0,开始执行代码2,p0发现p1也想访问临界区,所以p0会卡在代码2处循环等待,此时切换到p1开始执行代码6,p1发现p0也想访问临界区,所以p1会卡在代码6处循环等待,这就出现了两个进程都一直无法访问临界区的情况。违背了“空闲让进”和“有限等待”的原则。
4.Peterson算法
算法思想:在双标志后检查法中,两个进程都想进入临界区,最后导致都进不去。因此可以在双方都想进入临界区时,让进程进行谦让,主动让对方先使用临界区
- 在p0进程中,flag[0]表示自己想要进入临界区的意愿,turn=1表示自己愿意让p1进程先进入临界区。
- 因此当执行到代码3时,如果发现p1此时想进入临界区,并且最后一次是自己说愿意让p1先进入临界区,那么p0会先卡在代码3处循环等待。
- 如果发现p1此时不想进入临界区,或者最后一次的谦让是p1说愿意让p0先进入临界区,那么p0开始访问临界区,并且在访问完临界区后修改自己的意愿,表示自己不想访问临界区了。
- 该算法遵循了空闲让进,忙则等待,优先等待的原则,但没有遵循让权等待的原则。
五.进程互斥的硬件实现方法
1.中断屏蔽方法
利用“开/关中断指令”实现,与原语的实现方法类似,也就是从进程访问临界区开始直到结束,都不允许被中断,也不允许进程切换,因此就不会出现两个进程同时访问临界区的情况。
优点:简单,高效
缺点:
1.不适用于多处理机(因为开/关中断指定只会对开启它的处理机生效,如果有多个处理机,那么虽然当前处理机上的进程被控制,但是别的处理机的进程依然可以进行切换)
2.只适用于内核进程,因为开/关中断指令只能运行在内核态。
2.TestAndSetLock指令
简称 TSL指令,执行的过程不允许被中断,只能一气呵成,下面是用c语言描述的逻辑
3.Swap指令
有的地方也叫Exchange指令,它也是用硬件实现的,执行过程中不允许被中断,下面是用c语言描述的逻辑
- 也就是说先记录临界区是否上锁(记录在old中)
- 记录完之后不管此时临界区是否上锁,都要将临界区上锁
- 最后检查old,如果old为false,那说明之前没有进程将临界区上锁,说明此时没有进程在使用临界区,那么就可以跳出循环,访问临界区;如果old为true,说明临界区在此之前已经被上锁,表示此时有进程在访问临界区,那么继续循环等待。
- 优点:实现简单,适用于多处理机
- 缺点:不满足让权等待