计算机操作系统——死锁
前言:死锁:指多个进程因竞争共享资源而造成的一种僵局,若无外力作用,这些进程都将永远不能再向前推进。如果死锁发生,会浪费大量的系统资源,甚至会导致系统崩溃。
关于死锁的结论:
- 参与死锁的进程最少是两个
- 参与死锁的所有进程都在等待资源
- 参与死锁的进程是当前系统中所有进程的子集
一、死锁产生的必要条件
1. 互斥条件
进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程所占用。如果此时还有其他进程请求该资源,则请求进程只能等待,直至占有该资源的进程用完并释放资源。
2. 请求和保持条件
进程已经保持了至少一个资源,但又提出新的资源请求,而该进程已经被其他进程占有,此时进行请求的进程将被阻塞,进入阻塞队列,但是对自己已经获得的资源保持不放。
3. 不可抢占条件
进程已获得的资源在未使用之前不能被抢占,只能在进程使用完时由自己释放。
4. 循环等待条件
在发生死锁时,必然存在一个进程–资源的循环链,即进程集合{P0,P1,…,Pn}中的P0正在等待一个P1占用的资源,P1正在等待P2占用的资源,…,Pn正在等待已被P0占用的资源。
二、处理死锁的方法
1. 预防死锁
(1)破坏“请求和保持”条件
(2)破坏“不可抢占”条件
可剥夺资源:即当某进程新的资源未满足,释放已占有的资源
(3)破坏“循环等待”条件
资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反。
2. 避免死锁
利用银行家算法避免死锁。Dijkstra的银行家算法,原本是为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。
为实现银行家算法,每一个新进程在进系统时,它必须申明在运行过程中,可能需要每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程。如果有,再进一步运算将资源分配给该进程后,是否会使系统处于不安全状态。如果不会,才将资源分配给该进程。
银行家算法中的数据结构:
(1)可利用资源向量Available
代表可利用的资源数目。
(2)最大需求矩阵Max
代表各进程对各类资源的最大需求。
(3)分配矩阵Allocation
代表各进程当前已分配的各类资源数目。
(4)需求矩阵Need 代表各进程尚需要的各类资源数目。最大需求矩阵减去分配矩阵(Need[i,j] = Max[i,j] - Allocation[i,j])
银行家算法的过程:
银行家算法例题:
3. 检测死锁
为了能对系统中是否发生了死锁进行检测,在系统中必须:保存有关资源的请求和分配信息;提供一种算法,它利用这些信息来检测系统是否已经进入死锁状态。
安全性算法:
设置两个向量
a.工作向量Work:提供给进程继续运行所需的各类资源数目。它含有m个元素,在安全算法开始时Work = Available
b.Finash:它表示系统是否有足够的资源分配给进程,使之运行完成。开始时,先令Finish[i] = false;当有足够资源分配给进程时,再令Finish[i] = true;
4. 解除死锁
当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常用的方法:
(1)剥夺(抢占)资源法:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态。
(2)撤销(终止)进程法:可以直接撤销死锁进程或撤销代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓的代价是指优先级、运行代价、进程的重要性和价值等。
(3)进程回退法:需要设置还原点,让一个或多个死锁进程回退到足够避免死锁的地步。