操作系统之银行家算法大题解题思路(含例题)

扩展:

什么是死锁

在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。

死锁产生的四个必要条件:(有一个条件不成立,则不会产生死锁)

① 互斥条件:一个资源一次只能被一个进程使用

② 不剥夺条件:进程获得的资源,在未完全使用完之前,不能强行剥夺

③ 请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放

④ 循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系

如何处理死锁问题?

常用的处理死锁的方法有:死锁预防、死锁避免、死锁检测、死锁解除、鸵鸟策略。

(1)死锁的预防:基本思想就是确保死锁发生的四个必要条件中至少有一个不成立

① 破除资源互斥条件

② 破除“不可剥夺”条件:允许进程强行从占有者那里夺取某些资源。当一个已经保持了某些不可被抢占资源的进程,提出新的资源请求而不能得到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。这意味着进程已经占有的资源会被暂时被释放,或者说被抢占了。

③ 破除“请求与保持”条件:实行资源预分配策略,进程在运行之前,必须一次性获取所有的资源。缺点:在很多情况下,无法预知进程执行前所需的全部资源,因为进程是动态执行的,同时也会降低资源利用率,导致降低了进程的并发性。

④ 破除“循环等待”条件:实行资源有序分配策略,对所有资源排序编号,按照顺序获取资源,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。

(2)死锁避免:

死锁预防通过约束资源请求,防止4个必要条件中至少一个的发生,可以通过直接或间接预防方法,但都会导致低效的资源使用和低效的进程执行。而死锁避免则允许前三个必要条件,但是通过动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。

安全状态是指:如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的,换句话说就是,如果存在一个安全序列,那么系统处于安全状态。银行家算法是经典的死锁避免的算法。

(3)死锁检测:

死锁预防策略是非常保守的,通过限制访问资源和在进程上强加约束来解决死锁的问题。死锁检测则是完全相反,它不限制资源访问或约束进程行为,只要有可能,被请求的资源就被授权给进程。但是操作系统会周期性地执行一个算法检测前面的循环等待的条件。死锁检测算法是通过资源分配图来检测是否存在环来实现,从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示存在环,也就是检测到死锁的发生。

① 如果进程-资源分配图中无环路,此时系统没有死锁。

② 如果进程-资源分配图中有环路,且每个资源类中只有一个资源,则系统发生死锁。

③ 如果进程-资源分配图中有环路,且所涉及的资源类有多个资源,则不一定会发生死锁。

(4)死锁解除:

死锁解除的常用方法就是终止进程和资源抢占,回滚。

所谓进程终止就是简单地终止一个或多个进程以打破循环等待,包括两种方式:

① 终止所有死锁进程和一次只终止一个进程直到取消死锁循环为止;

② 所谓资源抢占就是从一个或者多个死锁进程那里抢占一个或多个资源。

(5)鸵鸟策略:

把头埋在沙子里,假装根本没发生问题。因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任何措施的方案会获得更高的性能。当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。

大多数操作系统,包括 Unix,Linux 和 Windows,处理死锁问题的办法仅仅是忽略它。

### 计算机操作系统中的银行家算法 #### 定义与背景 银行家算法是一种用于预防死锁的资源分配策略。该算法通过模拟资源分配过程来决定是否安全地分配资源给进程,从而避免进入不安全状态。 #### 示例题目解析 假设有一个系统中有五个进程 \(P_0, P_1, P_2, P_3,\) 和 \(P_4\) 请求三种类型的资源 A、B 和 C 的情况如下: | 进程 | Max | Allocation | Need | |------|--------|------------|----------| | \(P_0\) | 7 5 3 | 0 1 0 | 7 4 3 | | \(P_1\) | 3 2 2 | 2 0 0 | 1 2 2 | | \(P_2\) | 9 0 2 | 3 0 2 | 6 0 0 | | \(P_3\) | 2 2 2 | 2 1 1 | 0 1 1 | | \(P_4\) | 4 3 3 | 0 0 2 | 4 3 1 | 当前可用资源数量为 \((A=3, B=3, C=2)\)[^1]。 为了判断此状态下能否满足某个进程的新请求而不导致死锁发生,可以按照以下步骤操作: 1. **安全性检测** - 初始化工作向量 `Work` 设置为现有可用资源数 `(Available)`。 - 创建一个布尔数组 `Finish[]` 来跟踪哪些进程已完成其最大需求。 2. **寻找可完成进程** 如果存在未完成(`!Finish[i]`) 并且它的所需资源不超过剩余资源 (`Need_i ≤ Work`) 的进程,则执行下列动作: - 假设该进程已获得所有所需的额外资源并完成了任务; - 将这些释放出来的资源加回到总的工作集里 (`Work += Allocation_i`); - 标记此进程已经结束 (`Finish[i]=true`); 3. **重复上述过程直到无法找到符合条件的进程** 如果最终所有的进程都能被标记为完成,则说明初始配置处于安全状态;否则就表示可能存在潜在的死锁定风险。 对于上面的例子,在尝试运行银行家算法之前先计算总的可用资源以及各个进程的最大需求和实际占用情况。接着逐步测试每一个可能的安全序列,看是否存在一种方式可以让全部进程都顺利完成而不会陷入死锁困境之中。 ```python def bankers_algorithm(max_resources, allocated_resources, available_resources): need = [[max_resources[i][j] - allocated_resources[i][j] for j in range(len(max_resources[0]))] for i in range(len(max_resources))] n_processes = len(max_resources) n_resource_types = len(max_resources[0]) finish = [False] * n_processes work = list(available_resources) safe_sequence = [] while False in finish: found = False for p in range(n_processes): if not finish[p]: can_allocate = True for r in range(n_resource_types): if need[p][r] > work[r]: can_allocate = False break if can_allocate: for r in range(n_resource_types): work[r] += allocated_resources[p][r] finish[p] = True safe_sequence.append(p) found = True if not found: raise Exception('Unsafe state detected') return safe_sequence ```
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值