操作系统总结(七)死锁
什么是死锁
多个进程循环等待资源而无法继续执行的状况称之为死锁。其造成了进程的停止运行,也浪费了大量的资源。例如生产者消费者问题上,如果使用了不合理的信号量顺序就会造成死锁情况,如生产者消费者首先不会对空闲资源信号量和占有资源信号量执行P操作,相反,首先对互斥信号量执行P操作,这种情况下就会发生死锁。思考这样一种情况:当互斥信号量数值为1时生产者对互斥信号量执行了P操作,继续执行,假设此时空闲资源信号量为0,当生产者对其执行P操作后,生产者进程将会进入等待队列。此时,由于互斥信号量没有被释放,因此所有的消费者都没办法继续执行,此时所有进程都进入了等待状态,也就发生了死锁。
为什么产生死锁
多个进程等待资源会造成死锁,但是显然并不是所有的资源都会造成死锁。资源互斥访问是造成死锁的必要条件。(如打印机每一次只能让一个进程使用,就会造成死锁)。而同时死锁并不是总会发生,只有形成了循环等待才会发生死锁。
发生死锁的必要条件:
- 互斥使用:至少一个资源互斥使用
- 不可抢占:资源只能自愿放弃
- 请求和保持:进程必须占有自愿,然后再去申请
- 循环等待:在资源分配图中存在一个环路
消除死锁的方法
对死锁的处理可以有以下几种
死锁预防
- 破坏互斥使用,但是这一般是资源固有的属性,无法破除
- 破除不可抢占:如果一个进程占有了资源但无法获得其他需要的资源,那么此时其占有的资源可以被抢占。但是这种情况对IO等不含有现场保护的资源无效
- 破除请求和保持:在进程执行之前一次性获得所有的资源然后才运行。缺点:很多资源并不是马上用到,浪费资源。
- 破除循环等待:对资源类型进行排序,资源申请必须按序进行
这种方法会引入不合理的因素,一般很少使用
死锁避免
判断此次请求是否会造成死锁,会造成死锁就拒绝此次请求。如果所有的进程存在一个安全序列(可以顺利完成的进程序列)那么称系统处于安全序列。怎样找到这样的一个安全序列呢?
银行家算法
一个安全序列P1…Pn应该满足如下的条件:
Pi(1<=i<=n)需要资源 <=剩余资源 + 分配给Pj(1<=j<=i)资源
安全状态的判断思路如下:①初始化设定: Work = Available(动态记录当前剩余资源) Finish[i]=false(设定所有进程均未完成) ②查找这样的进程Pi(未完成但目前剩余资源可满足其需要,这样的进程是能够完成的): a)Finish[i] = false b)Need[i] <= Work 如果没有这样的进程Pi,则跳转到第④步 ③(若有则)Pi一定能完成,并归还其占用的资源,即: a)Finish[i] = true b)Work = Work +Allocation[i] GOTO 第②步,继续查找 ④如果所有进程Pi都是能完成的,即Finish[i]=ture 则系统处于安全状态,否则系统处于不安全状态
银行家算法缺点:
- 每个进程进入系统时必须告知所需资源的最大数量对应用程序员要求高。
- 安全序列寻找算法(安全状态判定算法)计算时间复杂度为O(mn2),过于复杂。
- 若每次资源请求都要调用银行家算法,耗时过大,系统效率降低。
- 采用此算法,存在情况:当前有资源可用,尽管可能很快就会释放,由于会使整体进程处于不安全状态,而不被分配,致使资源利用率大大降低
死锁检测和恢复
因为银行家算法复杂性较高,因此,使用此种方法来减小复杂度。即只要当前资源足够就分配,发现问题再处理。不过仍要执行银行家算法且恢复上并不容易。
死锁忽略
对死锁不做任何处理(UNIX就用这种#——#,现在用的最多)