银行家算法

算法目的:预防死锁

数据结构

假设有m个资源,n个进程。

  1. 可利用资源数组Available[m],Availabe[i]为i类资源现可用的数目;
  2. 最大需求矩阵Max[n*m],Max[i,j]为进程i需要j资源的最大数目;
  3. 分配矩阵Allocation[n*m],Allocation[i,j]为进程i当前已分配到j资源的数目;
  4. 需求矩阵Need[n*m],Need[i,j]为进程i还需要多少j资源才能完成。

银行家算法

  1. 找到一个所需的资源不大于现有资源的进程;
  2. 系统进行试探,把资源分配给该进程,更新Available、Allocation、Need数组;
  3. 执行安全性算法。

安全性算法

设置两个数组,work和finish。work = Available,finish[i] = 0。

  1. 从进程集合中找到一个能满足以下条件的进程:
    • finish[i] = 0
    • Need[I,*] <= work[*]
  2. 找到进程i获得资源后可顺利执行,直至完成,并释放分配给它的资源,执行以下步骤:
    • work[j] = work[j] + Allocation[i,j]
    • finish[i] = 1
    • go to step 1
  3. 如果finish全为1则处于安全状态。

代码:

Available = []
Max = []
Allocation = []
Need = []


def find_i(finish, ne, work):
    for i in range(len(finish)):
        flag = 0  # 记录每个进程可被满足资源的数量
        for j in range(len(work)):
            if finish[i] == 0:
                if work[j] < ne[i][j]:
                    continue
                else:
                    flag += 1
        if flag == len(work):  # 如果全都满足则可以运行该进程
            return I
    return -1


def safety(av, al, ne, choice):
    work = av[:]
    finish = [0] * m
    list = []
    while True:
        i = find_i(finish, ne, work)
        if i != -1:
            for j in range(len(work)):
                work[j] = work[j] + al[i][j]
            
            finish[i] = 1
            list.append(i)
        else:
            if len(finish) == len(tuple(finish)) and finish[0] == 1:
                if choice == 0:
                    print('该时刻存在的安全序列:', list)
                    return 1
                else:
                    return list
            else:
                return 0


if __name__ == '__main__':
    f = open('银行家.txt', 'r')
    lines = f.readlines()
    m = len(lines) - 1  # 进程数量
    # m = int(input('输入进程数量:'))
    Max = [[]] * m
    Allocation = [[]] * m
    Need = [[]] * m
    # n = int(input('输入资源数量:'))
    print(lines[0])
    lines[0] = list(map(lambda x: int(x), lines[0].split()))
    n = len(lines[0])  # 资源数量
    Available = lines[0]
    # for i in range(n):
    #     # Available.append(int(input('输入第'+str(i+1)+'个资源的数量:')))
    #     for j in range(m):
    #         Max[j].append(int(input('输入第'+str(j+1)+'个进程对该资源的最大需求:')))
    #         Allocation[j].append(int(input('输入第'+str(j+1)+'个进程已分配到的该资源:')))
    #         Need[j].append(int(input('输入第'+str(j+1)+'个进程还需多少该资源才能完成:')))
    lines = lines[1:]
    for i in range(len(lines)):
        lines[i] = list(map(lambda x: int(x), lines[i].split()))
        Max[i] = lines[i][:n]
        Allocation[i] = lines[i][n:2*n]
        Need[i] = lines[i][2*n:]
    for i in range(n):
        a = 0
        for j in range(m):
            a += Allocation[j][I]
        Available[i] -= a
    print(Available)
    list = []  # 安全序列

    while len(list) < m or not list:
        a = int(input('输入请求资源还是直接输出安全序列?'))
        if a == 0:
            flag = 1
            request = [int(i) for i in input('输入请求资源的进程及资源的数量:').split()]
            i = request[0]
            k = request[1:]  # 该进程对所有资源对需求
            av = Available[:]
            al = Allocation[:]
            ne = Need[:]
            for j in range(n):
                if k[j] <= Need[i][j] and k[j] <= Available[j]:
                    av[j] -= k[j]
                    al[i][j] += k[j]
                    ne[i][j] -= k[j]

                    # print(av)
                else:
                    print('没有足够的资源!')
                    flag = 0
            if safety(av, al, ne, 0) and flag:
                Allocation = al
                Available = av
                Need = ne
                list.append(i)
                print(list)
            else:
                print('不能分配!')
        else:
            list = safety(Available, Allocation, Need, 1)
            print(list)

可以选择自己输入还是读取本地文件。
本地文件内容如下:

10 5 7  # 有三个资源,每个资源可用的数量。
7 5 3 0 1 0 7 4 3  # 每个进程占一行,读文件的时候把注释删掉。
3 2 2 2 0 0 1 2 2  # 具体情况如下图所示。
9 0 2 3 0 2 6 0 0
2 2 2 2 1 1 0 1 1
4 3 3 0 0 2 4 3 1
计算机操作系统(第四版)113页
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • 死锁是多线程环境中由于对资源竞争分配不合理而产生的阻塞行为,银行家算法是一种动态避免死锁的策略。 I、死锁 1.1...
    wenmingxing阅读 4,971评论 0 8
  • 算法原理 我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当...
    Arya鑫阅读 863评论 0 1
  • 死锁常见的题目 定义 所谓死锁,是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。死锁是指两个或两个以上...
    analanxingde阅读 13,646评论 4 10
  • 死锁 在了解银行家算法前,有必要了解一下死锁。因为银行家算法是用于避免死锁的。 什么是死锁? 死锁是指两个或两个以...
    tandeneck阅读 1,234评论 0 1
  • 【易效能三只青蛙】 G179 三组 34- Li Pan-墨尔本-许大康 20180201 第88/90 飞 Ca...
    南半球的猫阅读 109评论 0 0