操作系统银行家算法实验
操作系统银行家算法实验,完整代码在文末
1、实验目的
加深了解死锁概念,体会产生死锁的原因,掌握避免死锁的具体实施方法。2、实验内容
编写一个系统动态分配资源的模拟程序,采用银行家算法有效地避免死锁的发生。要求程序能够在进程提出资源申请后判断系统是否处于安全状态,如果安全则打印资源分配表和安全序列:如果不安全则输出不能分配的提示。
3、算法设计
数据结构:
变量名 | 类型 | 注释 |
available | 一维数组 | 表示每种资源可用的数量 |
max | 二维数组 | 表示每个进程需要的最大资源数量 |
allocation | 二维数组 | 表示每个进程已经分配的资源数量 |
need | 二维数组 | 表示每个进程还需要的资源数量 |
work | 一维数组 | 表示每个进程可用的资源数量 |
finish | 一维数组 | 表示每个进程是否可以完成执行 |
n | 整数 | 表示系统中进程的数量 |
m | 整数 | 表示系统中资源的种类数量 |
本程序实现了银行家算法的基本逻辑,用于模拟资源管理和进程调度。用户可以通过输入请求来模拟不同的情况,以验证系统的安全性和资源分配策略。下面是银行家算法的设计说明:
(1)导入测试数据( loadTestData 函数):首先,代码导入了测试数据,包括可用资源向量( available )、最大需求矩阵( max_table )、分配矩阵( allocation )。这些数据模拟了系统中各个进程对资源的需求和分配情况。
(2)输出表格( printTable 函数):这个函数用于在控制台输出进程的最大需求、已分配资源、尚需资源情况,以及当前可用资源。这有助于用户了解系统的初始状态。
(3)安全性算法( security 函数):这是银行家算法的核心部分。它模拟了系统的安全性检查,以确保没有死锁的风险。具体步骤如下:
初始化一个布尔数组 finish ,表示每个进程是否完成,初始为全 False 。
进入一个循环,直到所有进程都完成:遍历每个进程,检查是否有未完成的进程,并且该进程的需求资源小于等于当前可用资源(即安全性检查)。如果找到一个满足条件的进程,输出它的标识(如"P0"),将其持有的资源释放给系统( work += allocation[i] ),并将该进程标记为已完成( finish[i] = True )。如果没有找到可执行的进程,返回 False ,表示系统处于不安全状态。
当循环结束后,返回 True ,表示系统是安全的。
(4)主函数( main 函数):这是程序的入口点。首先,它输出初始的资源分配情况,然后进入一个循环,用户可以输入进程的资源请求。主要步骤如下:
用户输入进程标识和资源请求,例如"P1, 1 0 1"。
程序判断资源请求的合法性,包括请求不得超过最大需求( max_table )、请求不得超过尚需资源( need )。
如果请求合法,程序尝试模拟资源分配,减少可用资源( available )、增加分配资源( allocation )、减少尚需资源( need )。
然后,程序调用 security 函数来检查系统是否处于安全状态。如果安全,系统会继续运行,输出新的资源状态;如果不安全,请求将被拒绝,资源状态回滚。
用户可以反复输入请求,直到系统进入不安全状态,或者用户终止程序。
4、运行与测试
图 6根据初始化后的系统数据打印资源分配表
图 7请求资源分配
图 8请求资源分配失败
模拟进程提出资源申请,系统进行安全状态检查,若安全则为其分配资源并更新资源分配表,若不安全或者不合法则输出相应提示
5、总结与心得
通过本次实验,我加深“银行家算法”核心思想的理解,就是在资源分配之前判断本次分配是否会导致系统进入不安全状态,根据这个判断决定是否同意资源分配请求。并且不安全状态未必就是发生了死锁,但发生死锁时一定是在不安全状态。
import numpy as np
def security(work, need, allocation):
"""安全性算法"""
n = need.shape[0] #读取矩阵第一维度的长度
finish = np.array([False] * n, dtype=bool) #系统是否有足够的资源分配给进程使之运行完成,初始化false
while not(finish.all()): # 当存在未完成的进程时循环执行以下操作
flag = False
for i in range(n):
if not finish[i] and (need[i] <= work).all(): # 如果进程未完成且当前可用资源满足进程的需求
print("P{}".format(i), end=' -> ')
flag = True
work += allocation[i] # 将进程持有的资源释放
finish[i] = True # 将该进程标记为已完成
break
if not flag:
return False
print()
return True
def printTable(available, max_table, allocation, need):
"""输出表格"""
print("=="*30)
print("进程\tMax\tAllo\tNeed")
for i in range(5):
print("P{}\t{}\t{}\t{}".format(
i, max_table[i], allocation[i], need[i]))
print("当前剩余资源:", available)
def loadTestData():
"""导入测试数据"""
return (np.array([10, 5, 7], dtype=int),
np.array([[7, 5, 3],
[3, 2, 2],
[9, 0, 2],
[2, 2, 2],
[4, 3, 3]], dtype=int),
np.array([[0, 1, 0],
[2, 0, 0],
[3, 0, 2],
[2, 1, 1],
[0, 0, 2]], dtype=int))
def main():
available, max_table, allocation = loadTestData()
need = max_table - allocation
# 计算出剩余资源
for i in allocation:
available -= i
printTable(available, max_table, allocation, need)
while (need != 0).any():
# 输入进程请求的请求资源
proc_ind, req = input("输入请求,如:P1, 1 0 1: ").split(',')
proc_ind = int(proc_ind[1:])
req = np.array(req.split(), dtype=int)
# 判断合法性
if (req > max_table[proc_ind]).any():
print("[ERROR] 请求资源大于所需资源,请重新输入")
continue # 重新输入
# 判断请求资源是否大于需求资源
if (req > need[proc_ind]).any():
print("[ERROR] 请求资源大于所需资源,请重新输入")
continue # 重新输入
# 判断安全性
else:
available -= req
allocation[proc_ind] += req
need[proc_ind] -= req
if security(available.copy(), need, allocation):
printTable(available, max_table, allocation, need)
continue
else:
print("[ERROR] 不安全,不能分配")
available += req
allocation[proc_ind] -= req
need[proc_ind] += req
if __name__ == '__main__':
main()
更多推荐
所有评论(0)