银行家算法的python实现

前言


写操作系统作业的时候,发现代码题没有要求语言,就试着用python写了。

《现代操作系统》第四版,第六章死锁的课后题41题:
41.Program a simulation of the banker’s algorithm. Your program should cycle through
each of the bank clients asking for a request and evaluating whether it is safe or unsafe. Output a log of requests and decisions to a file.

41.编写银行家算法的模拟程序。该程序应该能够循环检查每一个提出请求的银行客户,并且能判断这一请求是否安全。请把有关请求和相应决定的列表输出到一个文件中。


一、什么是银行家算法(Banker’s Algorithm)

简单的来说,就是每次分配资源之前检查一下这次分配会不会导致某个进程得不到足够的资源导致死锁,不会就分配,会就等待。


“银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全序列是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。” ——摘自百度百科


二、代码实现

1.requirements

为了方便矩阵运算,用了numpy, 同时因为要求输出logs,用了time。
numpy==1.20.2

from numpy import *
import time

2.定义变量

MAXN定义最大的线程数,MAXM定义资源种数。

logs存输出的日志的字符串。
Available存可使用的资源数,
MaxNeed存最大需求量,
Allocation存已分配的资源数,
Need存接下来还能要多少资源,
request存请求资源的矩阵,
logs存输出日志的字符串。

#N is quentity of processes. M is quentity of kinds of resources.
MAXN=5
MAXM=5
#define for resources scheduling
Available=full(MAXM,10)
MaxNeed=random.randint(1, 20, size=(MAXN, MAXM))
Allocation=zeros((MAXN, MAXM))
Need=MaxNeed-Allocation
#request matrix  [process NO, resource type]
request=zeros((MAXN, MAXM), int)
#logs of requests and decisions in string
logs='Banker\'s algorithm simulator \n@created by Concyclics\n\n'

3.检查本次分配是否安全

对于每一个进程,检查它用剩下的资源能否完成任务,如果可以,就把它已有的资源一起加入可分配的资源中,因为它可以很快地完成并释放资源。
work数组里存可用的资源,finish存能够结束的进程。
如果有进程不能结束,说明这种分配不安全。

#the function to check the allocation is safe or not
def safe():
	work=Available
	finish=full(MAXN, 0)
	for i in range(MAXN):
		if finish[i]==0:
			for j in range(MAXM):
				if Need[i][j]<=work[j]:
					work[j]+=Allocation[i][j]
				else:
					break
			finish[i]=1
	for i in finish:
		if i ==0:
			return False
	return True

4.分配函数

从request中顺序读取请求并执行模拟分配,用safe()函数检查是否安全。

#function for allocating by the request matrix
def bank():
	global logs
	Need=MaxNeed-Allocation
	for i in range(MAXN):
		for j in range(MAXM):
			logs+='\nin '+time.strftime('%Y年 %m月 %d日 %H:%M:%S',time.localtime(time.time()))
			logs+='\nProcess '+str(i)+' requests for '+str(request[i][j])+' resource type:'+str(j)+'\n result:\n'
			if request[i][j]>Need[i][j] or request[i][j]>Available[j]:
				logs+='the request is too large! Failed!\n'
			elif request[i][j]<=Available[j]:
				Available[j]-=request[i][j]
				Allocation[i][j]+=request[i][j]
				Need[i][j]-=request[i][j]
				if safe()==False:
					Available[j]+=request[i][j]
					Allocation[i][j]-=request[i][j]
					Need[i][j]+=request[i][j]
					logs+='the request will make the system danger! Wait!\n'
				else:
					logs+='the request is safe. Success.\n'

5.完整代码

#by concyclics

'''
filename Banker.py
version of Python 3.8.2
requirements:
numpy==1.20.2
'''
from numpy import *
import time

#N is quentity of processes. M is quentity of kinds of resources.
MAXN=5
MAXM=5
#define for resources scheduling
Available=full(MAXM,10)
MaxNeed=random.randint(1, 10, size=(MAXN, MAXM))
Allocation=zeros((MAXN, MAXM))
Need=MaxNeed-Allocation
#request matrix  [process NO, resource type]
request=zeros((MAXN, MAXM), int)
#logs of requests and decisions in string
logs='Banker\'s algorithm simulator \n@created by Concyclics\n\n'

#the function to check the allocation is safe or not
def safe():
	work=Available
	finish=full(MAXN, 0)
	for i in range(MAXN):
		if finish[i]==0:
			for j in range(MAXM):
				if Need[i][j]<=work[j]:
					work[j]+=Allocation[i][j]
				else:
					break
				finish[i]=1
	for i in finish:
		if i ==0:
			return False
	return True

#function for allocating by the request matrix
def bank():
	global logs
	Need=MaxNeed-Allocation
	for i in range(MAXN):
		for j in range(MAXM):
			logs+='\nin '+time.strftime('%Y年 %m月 %d日 %H:%M:%S',time.localtime(time.time()))
			logs+='\nProcess '+str(i)+' requests for '+str(request[i][j])+' resource type:'+str(j)+'\n result:\n'
			if request[i][j]>Need[i][j] or request[i][j]>Available[j]:
				logs+='the request is too large! Failed!\n'
			elif request[i][j]<=Available[j]:
				Available[j]-=request[i][j]
				Allocation[i][j]+=request[i][j]
				Need[i][j]-=request[i][j]
				if safe()==False:
					Available[j]+=request[i][j]
					Allocation[i][j]-=request[i][j]
					Need[i][j]+=request[i][j]
					logs+='the request will make the system danger! Wait!\n'
				else:
					logs+='the request is safe. Success.\n'


if __name__=='__main__':
	i=0
	for x in Available:
		logs+='resource type'+str(i)+' quentity: '+str(x)+'\n'
		i+=1
	logs+='\n'+'MaxNeed matrix i for process, j for resource'
	logs+='\n'+str(MaxNeed)+'\n'
	request+=random.randint(1, 5, size=(MAXN,MAXM))
	bank()
	print(logs)
	#write logs into file Banker_logs.txt
	with open('Banker_logs.txt','w',encoding='utf-8') as fileLogs:
		fileLogs.write(logs)
	

三、我的仓库

存放了我写的一些作业。
链接: Github仓库.
链接: Gitee仓库.
求个star ❤️ ❤️ ❤️
代码链接: 银行家算法的python实现.

  • 16
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
银行家算法是避免死锁的一种重要方法,本程序用java编程语言对其进行了实现。 当用户申请一组资源时,系统必须做出判断,如果把这些资源分出去,系统是否还处于安全状态。 若是,就可以分出这些资源;否则,该申请暂不予满足。 1.数据结构 假设有M个进程N类资源,则有如下数据结构: MAX[M*N] M个进程对N类资源的最大需求量 AVAILABLE[N] 系统可用资源数 ALLOCATION[M*N] M个进程已经得到N类资源的资源量 NEED[M*N] M个进程还需要N类资源的资源量 2.银行家算法 设进程I提出请求Request[N],则银行家算法按如下规则进行判断。 (1)如果Request[N]<=NEED[I,N],则转(2);否则,出错。 (2)如果Request[N]<=AVAILABLE,则转(3);否则,出错。 (3)系统试探分配资源,修改相关数据: AVAILABLE=AVAILABLE-REQUEST ALLOCATION=ALLOCATION+REQUEST NEED=NEED-REQUEST (4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。 3.安全性检查 (1)设置两个工作向量WORK=AVAILABLE;FINISH[M]=FALSE (2)从进程集合中找到一个满足下述条件的进程, FINISH[i]=FALSE NEED<=WORK 如找到,执行(3);否则,执行(4) (3)设进程获得资源,可顺利执行,直至完成,从而释放资源。 WORK=WORK+ALLOCATION FINISH=TRUE GO TO 2 (4)如所有的进程Finish[M]=true,则表示安全;否则系统不安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

concyclics

可怜可怜孩子吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值