银行家算法
-
实验要求
编程实现银行家算法。 -
流程图
-
代码
import threading import time import datetime import numpy as np from copy import deepcopy class Process: def __init__(self, id:int,allocation:np.ndarray,need:np.ndarray): self.id = id self.allocation = allocation self.need = need self.isfinish = False def request(self,request:np.ndarray): global available if self.isfinish: raise Exception('Error! Process {} has finished!'.format(hex(self.id))) elif (self.need<request).any(): raise Exception('Error! Request is larger than the process need') elif (available<request).any(): print('Error! Request is larger than the available') return False else: self.allocation += request self.need -= request available -= request if checksafe(print=True): print("If accept it the system will be Safe.") if (self.need==0).all(): self.isfinish = True return True else: print("If accept it the system will be Dangerous.") self.allocation -= request self.need += request available += request return False def checksafe(print=False): global available global processes available_bak = deepcopy(available) processes_bak = deepcopy(processes) p_list = [] for _ in range(len(processes_bak)): all_finish = True for process in processes_bak: if process.isfinish: continue elif (process.need<=available_bak).all(): available_bak += process.allocation process.need -= process.need process.allocation -= process.allocation process.isfinish = True p_list.append(hex(process.id)) break else: all_finish = False if print: printtable(available=available_bak,processes=processes_bak) if all_finish: printtable(available=available,processes=processes) return True else: return False def banker(): if checksafe(): print('The initial system is safe') while (ans:=input('Do you want continue?(Yy/Nn)')) and ans in 'Yy': while True: try: pid = int(input('Please input the process id:'),16) try: process = processes[pid2index[pid]] except: print('Error! The process id is not exist') raise Exception() break except: print('Please input a correct number!') while True: try: request = np.array(input('Please input the request:'\ ).split(' '),dtype=int) break except: print('Please input a number!') try: if not process.request(request): break except Exception as e: print(e) continue else: print('The initial system is not safe') def printtable(available,processes): print('\n') print('Available:',available) print('\n') for process in processes: print('Process',hex(process.id),'allocation:',\ process.allocation,'need:',process.need) num_processes = np.random.randint(5,20) available = np.random.randint(num_processes-5,num_processes+5,size=3) processes = [] pid2index = {} for i in range(num_processes): processes.append(Process(id=np.random.randint(0,1e9),\ allocation=np.random.randint(1,10,size=3),\ need=np.random.randint(1,10,size=3))) pid2index[processes[i].id] = i banker()
-
模拟优化
- 初始资源数随机生成
- 后续资源申请需要用户手动输入(不然太容易直接不安全或者直接申请资源错误)
- 充足的异常处理避免用户输错
-
运行方式
python exp3.py
-
运行结果
-
运行结果分析
- 一开始系统处于安全状态
- 进程0xc1530e7申请资源5 0 0后系统仍处于安全状态,剩余资源为[2 4 6]刚好与进程0x20a75e03所需资源一致,并且之后可以产生安全序列
- 进程0x12d3f5cb申请资源1 0 0后系统处于不安全状态,剩余资源为[1 4 6],小于进程0xc1530e7所需资源