银行家算法python实现Dijkstra

银行家算法python实现Dijkstra

题目要求

  1. 假定系统有3类资源A(10个)、B(15个)、C(12个),系有5个进程并发执行,进程调度采用时间片轮转调度算法。
  2. 每个进程由一个进程控制块( PCB)表示,进程控制块可以包含如下信息:进程名、需要的资源总数、已分配的资源数、进程状态。
  3. 由程序自动生成进程(包括需要的数据,要注意数据的合理范围)。
  4. 进程在运行过程中会随机申请资源(随机生成请求的资源数),如果达到最大需求,表示该进程可以完成;如果没有达到最大需求,则运行一个时间片后,调度其它进程运行。资源分配采用银行家算法来避免死锁。
  5. 每个进程的状态可以是就绪 W(Wait)、运行R(Run)、阻塞B(Block)或完成F(Finish)状态之一。
  6. 每进行一次调度,程序都要输出一次运行结果:正在运行的进程、就绪队列中的进程、阻塞队列中的进程、完成的进程以及各个进程的 PCB,以便进行检查。

银行家算法原理

原理
这里不再赘述

分析

本算法中有几个矩阵:需求矩阵need,用于保存和更新每个进程的实时需要;请求矩阵request, 用于保存和更新每个进程的实时请求;分配矩阵allocation, 用于保存和更新每个进程的实时分配;每个进程的PCB保存了该进程的名字、状态、对各资源的最大需求、和已分配给该进程的资源数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进程调度采用时间片轮转的方式。进程初始状态为就绪状态。当进程申请资源时,在以下两种情况会进入阻塞:1.资源不足;2.若同意该资源申请系统会进入不安全状态,即不能通过安全性算法。进入阻塞的进程就失去申请资源的权限。再每次进程调度时,会遍历阻塞队列,当当前资源数满足阻塞进程需求时,则加入就绪队列。当就绪队列的第一个进程尝试申请资源时,将进行安全性检测;此时会试探着将资源分配出去,即将需求矩阵、分配矩阵和可用资源向量Available复制一次,对复制的矩阵进行安全性判断;若系统安全则将资源分配出去,并更新需求矩阵、分配矩阵和可用资源向量Available等。

代码

这里给出仅为主体代码,测试部分较为简单,可以自行补充,或者关注以下公众号,回复100904获得全部代码
在这里插入图片描述

"""
2020/06本代码为本人实验内容,有需要的人可做参考,请勿直接ctrl c+v copy
函数命名和个别变量名请改成自己需要的名字
"""
import random
import numpy as np
import copy
class PCB:
    def __init__(self,name,state,need_A_max,need_B_max,need_C_max,all_A ,all_B ,all_C ): ##初始化进程
        self.name = name          #进程名字
        self.state=state          #状态
        self.need_A_max = need_A_max     #最大需求A资源
        self.need_B_max = need_B_max
        self.need_C_max = need_C_max
        self.all_A = all_A                  #已经为该进程分配的A
        self.all_B = all_B
        self.all_C = all_C
    def output(self):     #时间片轮转输出
        # print("本程序资源默认顺序为A B C")
        # print("进程名字     各类资源最大需求     已经分配资源     状态")  #1+3+3+1
        print('%-13s%-4s%-4s%-12s%-4s%-4s%-8s%-10s' % (str(self.name), str(self.need_A_max), str(self.need_B_max), str(self.need_C_max),str(self.all_A)
                                                       ,str(self.all_B),str(self.all_C),str(self.state)))
    def Run(self):    ##将状态置为Run
        self.state="Run"
    def Finish(self):     ##将状态置为Finish
        self.state="Finish"
    def Wait(self):      ##将状态置为Wait
        self.state="Wait"
    def Block(self):
        self.state="Block"   #阻塞

    def running(self,Available1,allocation1,need1):
        # 安全性算法
        i = 0
        Finish = [False,False,False,False,False]
        work = [0,0,0]
        k = 0
        cwj_dex = 0
        for f in range(3):
            Available1[f] = Available[f] - request[int(list[0].name)][f]
            allocation1[int(list[0].name)][f] = allocation[int(list[0].name)][f] + request[int(list[0].name)][f]
            need1[int(list[0].name)][f] = need[int(list[0].name)][f] - request[int(list[0].name)][f]
        for mm in range(3):
            #可以和上面循环合并
            work[mm] = Available1[mm]
            # for u in range(3):
        l = 0
        while l<5:
            for g in range(5):
                if(  (need1[g][0]<=work[0])  and Finish[g] == False and (need1[g][1]<=work[1]) and (need1[g][2]<=work[2]) ):

                    # and need1[int(list[0].name)][g]<work[g]
                    work[0] = work[0] + allocation1[g][0]
                    work[1] = work[1] + allocation1[g][1]
                    work[2] = work[2] + allocation1[g][2]
                    Finish[g] = True
                    break

            l += 1
        #检查Finishw
        for haha in range(5):

            if(Finish[haha] == False):
                #不安全
                k = 1
                break
        if (k == 0):
            cwj_dex = 1

        return cwj_dex

def initialization_ChenWJ(num):
    #初始化进程和可利用资源向量,开始为10,15,12
    list0=[]   #就绪队列

    for i in range(num):
        list0.append(PCB(str(i),"Wait",random.randint(0,10),
                        random.randint(0,15),random.randint(0,12),0,0,0))
    for c in range(5):
        need[c][0] = int(list0[c].need_A_max)
        need[c][1] = int(list0[c].need_B_max)
        need[c][2] = int(list0[c].need_C_max)
    print(need)
    return list0

def RR_time():
    #时间片轮转算法
    #list 就绪队列  list_b  阻塞队列
    cwj_dex = 0#0表示系统不安全
    list_b = []
    time = 0
    cwj = 0 #调度锁
    RR_time = 3  #时间片长度
    list_cwj = []
    while(1):

        print("time:", time)
        if (cwj == 0):
            #获得调度权限
            print("剩余",end = "")
            print("A:"+str(int(Available[0]))+" B:"+str(int(Available[1]))+" C:"+str(int(Available[2])))

            if(list):
                # 给就绪队列头随机生成请求资源

                need[int(list[0].name)][0] = list[0].need_A_max - list[0].all_A
                need[int(list[0].name)][1] = list[0].need_B_max - list[0].all_B
                need[int(list[0].name)][2] = list[0].need_C_max - list[0].all_C
                for m in range(3):
                    request[int(list[0].name)][m] = random.randint(0,need[int(list[0].name)][m])  #设定请求量小于需求



                #调度前打印打印就绪队列
                print("**********************************************")
                print("目前就绪进程如下所示:")
                print("进程名字     各类资源最大需求     已经分配资源     状态")  # 1+3+3+1

                for i in range(len(list)):

                    print('%-13s%-4s%-4s%-12s%-4s%-4s%-8s%-10s' % (str(list[i].name), str(list[i].need_A_max), str(list[i].need_B_max), str(list[i].need_C_max), str(int(list[i].all_A))
                                                                   , str(int(list[i].all_B)), str(int(list[i].all_C)), str(list[i].state)))
                print("目前阻塞进程如下所示:")
                print("进程名字     各类资源最大需求     已经分配资源     状态")  # 1+3+3+1
                if (not list_b):
                    print("无阻塞进程")
                for i in range(len(list_b)):

                    print('%-13s%-4s%-4s%-12s%-4s%-4s%-8s%-10s' % (str(list_b[i].name), str(list_b[i].need_A_max), str(list_b[i].need_B_max), str(list_b[i].need_C_max), str(list_b[i].all_A)
                                                                   , str(list_b[i].all_B), str(list_b[i].all_C), str(list_b[i].state)))
                print("**********************************************" + "\n")
            if (list_b):


                print("正在检测阻塞队列")
                y = 0
                index_btow = []
                for y in range(len(list_b)):
                    #判断能否变成就绪
                    if((request[int(list_b[y].name)][0] <= Available[0]) and (request[int(list_b[y].name)][1] <= Available[1]) and
                        (request[int(list_b[y].name)][2] <= Available[2])):
                        index_btow.append(y)
                for wo in range(len(index_btow)):
                    list_b[index_btow[wo]].Wait()
                    list.append(list_b[index_btow[wo]])

                    print("进程" + str(list_b[index_btow[wo]].name) + "已经从阻塞转换成就绪")

                for wo1 in range(len(index_btow)-1,-1,-1):
                    list_b.remove(list_b[index_btow[wo1]])
                index_btow.clear()

        if (list):  #执行过程
            print("进程"+str(list[0].name)+"运行"+",剩余时间片"+str(RR_time-1)+",总时间片"+str(3))
            print("进程"+str(list[0].name)+"   申请了A:"+str(int(request[int(list[0].name)][0])) +"   申请了B:"+str(int(request[int(list[0].name)][1])) +"   申请了C:"+str(int(request[int(list[0].name)][2]) )       )
                #判断当前资源是不是够分配
            if ((request[int(list[0].name)][0] <= Available[0]) and (request[int(list[0].name)][1] <= Available[1]) and (request[int(list[0].name)][2] <= Available[2])):
                #满足,尝试分配

                allocation1 = copy.deepcopy(allocation)
                Available1 = copy.deepcopy(Available)
                need1 = copy.deepcopy(need)
                cwj_dex = list[0].running(Available1,allocation1,need1)
                if(cwj_dex == 1):
                    #系统安全,正式分配资源,可以运行
                    list[0].Run()
                    for f in range(3):
                        Available[f] = Available[f] - request[int(list[0].name)][f]
                        allocation[int(list[0].name)][f] = allocation[int(list[0].name)][f] + request[int(list[0].name)][f]
                        need[int(list[0].name)][f] = need[int(list[0].name)][f] - request[int(list[0].name)][f]

                    print("该资源申请成功!")
                    list[0].all_A = allocation[int(list[0].name)][0]
                    list[0].all_B = allocation[int(list[0].name)][1]
                    list[0].all_C = allocation[int(list[0].name)][2]
                    RR_time -= 1  #有进程成功申请进程,时间才用完

                else:
                    #不安全阻塞
                    print("进程"+str(list[0].name)+"因为系统不安全,进入阻塞")
                    list[0].Block()
                    list_b.append(list[0])
                    list.remove(list[0])

            else:
                #资源不够,阻塞
                print("进程" + str(list[0].name) + "因为资源不够,进入阻塞")
                list[0].Block()
                list_b.append(list[0])
                list.remove(list[0])



            if (RR_time == 0):
                #时间片用完

                if(((list[0].need_A_max-list[0].all_A) == 0) and ((list[0].need_B_max-list[0].all_B) == 0) and ((list[0].need_C_max-list[0].all_C) == 0) ):
                    #资源达到最大要求
                    list[0].Finish()
                    for p in range(3):
                        allocation[int(list[0].name)][p] = 0
                        allocation1[int(list[0].name)][p] = 0
                    Available[0] = Available[0] + list[0].all_A
                    Available[1] = Available[1] + list[0].all_B
                    Available[2] = Available[2] + list[0].all_C
                    Available1[0] = Available1[0] + list[0].all_A
                    Available1[1] = Available1[1] + list[0].all_B
                    Available1[2] = Available1[2] + list[0].all_C
                    print("*****!!!进程" + list[0].name + "执行完毕"  + "!!!*****")
                    list.remove(list[0])


                else:
                    #未运行完,该进程放到就绪队列末尾
                    list[0].Wait()
                    list_cwj.append(list[0])
                    list.remove(list[0])
                    list.append(list_cwj[0])
                    list_cwj.remove(list_cwj[0])   #再次清空备用列表

                cwj = 0  # 开权限为调度做准备
                RR_time = 3  # 时间片长度
                print("#####!!!该时间片已经用完!!!#####")
            if (RR_time>0 and list):

                if( ((list[0].need_A_max-list[0].all_A) == 0) and ((list[0].need_B_max-list[0].all_B) == 0) and ((list[0].need_C_max-list[0].all_C) == 0)):
                #时间片未用完,该进程已经运行完
                    list[0].Finish()
                    for p in range(3):
                        allocation[int(list[0].name)][p] = 0
                        allocation1[int(list[0].name)][p] = 0
                    Available[0] = Available[0] + list[0].all_A
                    Available[1] = Available[1] + list[0].all_B
                    Available[2] = Available[2] + list[0].all_C
                    Available1[0] = Available1[0] + list[0].all_A
                    Available1[1] = Available1[1] + list[0].all_B
                    Available1[2] = Available1[2] + list[0].all_C
                    print("*****!!!进程" + list[0].name + "执行完毕" + "!!!*****")
                    list.remove(list[0])

                    cwj = 0
                    RR_time = 3  # 时间片长度
        time += 1
        # if (time == 35):
        #     break
        if (not list and not list_b):
            print("所有进程都运行完毕")
        #如果空,退出
            break
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值