进程互斥的实现方法
刚才读书的时候看到了进程互斥的实现方法这一章,想到之前面试的时候被问到这一部分的内容,今天来整理总结一下。
-
软件方法
- 单标志法
- 算法思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每一个进程进入临界区的权限只能被另一个进程赋予。
- 算法实现:
- 单标志法
-
-
- 该算法可以实现“同一时刻最多只允许一个进程访问临界区”。
- 单标志法存在的主要问题是:违背“空闲让进”原则。因为如果是允许P1进入临界区,但是P1一直不访问临界资源,那么虽然这个时候临界区是空闲的,但是并不允许P0访问。
-
-
- 双标志先检查法
- 算法思想:设置一个布尔型数组flag[],数组中各元素用来标记各进程想要进入临界区的意思,比如“flag[0] = ture”意味着0号进程P0想要进入临界区。每个进程进入临界区之前先检查当前有没有别的想要进入临界区的进程,如果没有则把自身对应的标志falg[i]设为true,之后开始访问临界区。
- 算法实现:
- 双标志先检查法
-
-
- 双标志法的主要问题是:违反“忙则等待”原则。其原因在于,进入区的“检查”和“上锁”两个处理不是一气呵成的。
- 双标志后检查法
- 算法思想:双标志先检查法的改进版。因为双标志先检查法存在的问题是“检查”和“上锁”不是一气呵成的,因此导致了同时进入临界区的问题。为了避免上述问题,人们想到了先“上锁”后“检查”的方法。
- 算法实现:
-
-
-
- 双标志后检查法虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待”原则,因此会导致各进程长期无法访问临界资源从而产生“饥饿”现象。
- Peterson算法
- 算法思想:结合双标志法、单标志法的思想。单标志法存在的问题是,当前进程没有使用临界资源的意愿,但是却得到了使用临界资源的权利,从而导致另一个想要使用临界资源的进程没办法访问正在空闲着的临界资源。而双标志后检查法中当两个进程都表达了想要使用临界资源的意愿后,由于双方都不想放弃使用的意愿,从而都没办法使用临界资源。Peterson算法结合这两种算法,只有当进程有想要使用临界资源的意愿时,才允许该进程进入临界区(解决单标志法的不足);两个进程在使用临界资源之前先表达“谦让”,最后一个表达“谦让”进程放弃使用的权利(解决双标志后检查法的不足)。
- 算法实现:
-
-
-
- Peterson算法用软件方法解决了进程互斥问题,遵循了空闲让进、忙则等待、有限等待三个原则,但是依然未遵循让权等待的原则。
-
-
硬件实现方法
- 中断屏蔽方法
- 原理:利用“开/关中断指令”实现(与原语的实现思想相同,即在某进程开始访问临界资源区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个进程同时访问临界区的情况)
- 方法:
- 中断屏蔽方法
-
-
- 优点:简单、高效
- 缺点:不适用于多处理机;只适用于操作系统内核进程,不适用于用户进程(因为开/关中断指令只能在内核态运行)
- TestAndSet指令
-
-
-
- 原理:TS(或TSL)指令是硬件实现的,执行过程不能被中断,只能一气呵成。
- 方法:
-
-
-
- 优点:实现简单,无需像软件方法严格检查是否有逻辑漏洞;适用于多处理机环境。
- 缺点:不满足“让权等待”原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。
- Swap指令
-
-
-
- 原理:硬件实现,一气呵成
- 方法:
-
-
-
- 优点:同TSL。
- 缺点:同TSL。
-
-
信号量机制
之前提到的两种方法都无法实现“让权等待”的原则,1965年,Dijkstra提出了信号量机制来解决这一问题。
信号量:就是一个变量,可以用信号量来表示系统中某种资源的数量。
原语:是一种特殊的程序段,其执行只能一气呵成,不能被打断。
-
- 整型信号量
- 定义:用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。
- 实现方法:
- 整型信号量
-
-
- 缺点:仍然不能够满足“让权等待”原则,会发生“忙等”。
- 记录型信号量
- 定义:用记录型数据结构表示的信号量。
- 实现方法:
-
永远渴望,大智若愚(stay hungry, stay foolish)