上节了解了进程同步与进程互斥
现在看看进程互斥的软件实现方法
单标志法
两个进程在访问完临界区后会把使用临界区的权限交给另一个进程
也就是说每个进程进入临界区的权限只能由另一个进程赋予
缺点:
当允许进入临界区的进程是p0, 但是p0一直不访问临界区
虽然这时候临界区是空闲的, 但是不允许其他进程访问
违背了空闲让进原则
双标志先检查
设置一个布尔型数组 flag[]
下标作为进程的id
false则表示该进程不想访问临界区, ture表示该进程想要访问临界区
每个进程在进入临界区之前先检查当前有没有其他的进程想要进入临界区
如果没有则把自身对应的flag[i]设为true然后访问临界区
很明显上述方法容易引起两个进程同时访问临界区
例如按照152637…的顺序执行
违反了"忙则等待"原则
因为进入区的"检查"与"上锁", 不是一气呵成的, 即没有原语的那种原子性
而 检查 与 上锁 之间可能发生进程的切换
双标志后检查
是双标志先检查方法的改良版本
之前是先检查再上锁
现在改成先上锁再检查
但是这样又引出新问题,
如上按1526…执行, 两个进程都无法进入临界区
虽然解决了"忙则等待", 但是又违背了 “空闲让进"和"有限等待”
可能导致双方长期无法访问资源而引起 "饥饿"现象
Peterson算法
结合单双标志法, 如果双方都想进入临界区, 则尝试让对方进入(‘孔融让梨’)
由上图可见, 在双方都想要访问临界区时(flag标志都为true),
谁后执行turn = 对方,那么谁就会暂缓进入临界区
换句话说, 谁先执行turn = 对方, 谁就先进入临界区
(上图p0,p1共享一个turn)
虽然Peterson算法遵循了 空闲让进, 忙则等待, 有限等待三个原则
但是未遵循让权等待, 即某进程无法进入临界区时, 该进程立即让出cpu