面试题答案
一键面试死锁避免算法设计
资源分配图算法(Resource Allocation Graph Algorithm)
- 数据结构:
- 任务表:记录每个任务的ID、任务类型(周期性或非周期性)、已分配资源列表、资源需求列表。
- 资源表:记录每种资源的总量、已分配量、可用量。
- 资源分配图:图的节点为任务和资源,边表示任务对资源的请求或资源分配给任务。
- 算法步骤:
- 初始化:根据系统中任务和资源的初始状态,填充任务表、资源表和构建资源分配图。
- 任务请求资源:
- 当一个任务请求资源时,首先检查资源表中该资源的可用量是否满足请求。如果不满足,任务进入等待状态。
- 如果满足,尝试在资源分配图中添加一条从任务到资源的请求边。
- 检查资源分配图是否存在环。可以使用深度优先搜索(DFS)算法进行检测。如果存在环,说明可能发生死锁,撤销刚才添加的请求边,任务继续等待;如果不存在环,将请求边转换为分配边,更新资源表和任务表中资源分配信息。
- 任务释放资源:
- 当一个任务完成或暂时不需要某些资源时,释放这些资源。在资源分配图中删除任务到这些资源的分配边,并更新资源表中资源的可用量。
应对复杂因素
- 周期性任务:
- 对于周期性任务,在任务表中记录其周期信息。每次任务周期到来时,按照上述请求资源步骤进行资源请求。在任务完成后,按照释放资源步骤释放资源,以便下一个周期使用。
- 可以根据任务周期的长短和资源需求的优先级,对任务进行调度,优先满足周期短且重要的周期性任务的资源需求。
- 资源需求不确定性:
- 由于任务对资源的需求不确定,在算法设计中,我们不依赖于事先知道任务的所有资源需求。每次任务请求资源时,即时检查资源可用性和死锁可能性。
- 对于非周期性任务,同样按照上述请求和释放资源的步骤进行处理。虽然其请求时间不确定,但算法可以动态地应对其资源请求。
复杂度分析
时间复杂度
- 请求资源时:检查资源可用性的时间复杂度为 $O(1)$,因为资源表可以直接查询。添加请求边并检查环的操作,使用DFS算法,其时间复杂度为 $O(V + E)$,其中 $V$ 是节点数(任务数 + 资源数),$E$ 是边数。在最坏情况下,假设任务数为 $n$,资源种类数为 $m$,则 $V = n + m$,$E$ 最多为 $n \times m$,所以时间复杂度为 $O(n + m + n \times m)$,近似为 $O(n \times m)$。
- 释放资源时:删除分配边和更新资源表的操作时间复杂度为 $O(1)$。
空间复杂度
- 任务表:存储每个任务的信息,假设每个任务需要记录的信息为常数 $c_1$,则任务表的空间复杂度为 $O(n \times c_1)$,近似为 $O(n)$。
- 资源表:存储每种资源的信息,假设每种资源需要记录的信息为常数 $c_2$,则资源表的空间复杂度为 $O(m \times c_2)$,近似为 $O(m)$。
- 资源分配图:使用邻接表存储图,空间复杂度为 $O(V + E)$,即 $O(n + m + n \times m)$,近似为 $O(n \times m)$。
- 总体空间复杂度为 $O(n + m + n \times m)$,近似为 $O(n \times m)$。
对系统整体性能的影响
- 优点:
- 该算法可以有效地避免死锁的发生,保证系统的稳定性。
- 由于是动态检测死锁,能够适应任务资源需求不确定性和任务的动态变化。
- 对于周期性任务,通过合理调度可以保证其周期性执行,满足实时性要求。
- 缺点:
- 时间复杂度较高,特别是在任务数和资源种类较多时,每次请求资源都需要检查环,会增加系统开销,可能导致任务响应时间变长。
- 空间复杂度也较高,需要维护任务表、资源表和资源分配图,可能占用较多的内存资源。在系统资源紧张时,可能对系统性能产生一定影响。