实验要求

一、 实验目的
死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。
二、 实验要求
设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。
系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析;
三、 数据结构
1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。
2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。
3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。
4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。
上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j);
四、 银行家算法
参考教材P96
五、 安全性算法
1. 设置两个向量。
Work:它表示系统可提供给进程继续运行的各类资源数目,它包含m个元素,开始执行安全性算法时,Work = Available。
Finish:它表示系统是否有足够的资源分配给进程,使之运行完成,开始Finish(I)=false;当有足够资源分配给进程Pi时,令Finish(i)=true;
2. 从进程集合中找到一个能满足下述条件的进程。
Finish(i)= = false;
Need i ≤work;
如找到则执行步骤3;否则,执行步骤4;
3. 当进程Pi获得资源后,可顺利执行直到完成,并释放出分配给它的资源,故应执行
Work = work + Allocation i
Finish(i)=true;转向步骤2;
4. 若所有进程的Finish(i)都为true,则表示系统处于安全状态;否则,系统处于不安全状态。
六、流程

操作系统 进程调度-银行家算法实验报告_银行家算法

实验报告

1.实验目的

死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。

2.实验内容与要求

①实验内容
1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。

2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。

3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。

4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。
上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j);

安全性算法
1. 设置两个向量。

Work:它表示系统可提供给进程继续运行的各类资源数目,它包含m个元素,开始执行安全性算法时,Work = Available。

Finish:它表示系统是否有足够的资源分配给进程,使之运行完成,开始Finish(I)=false;当有足够资源分配给进程Pi时,令Finish(i)=true;

2. 从进程集合中找到一个能满足下述条件的进程。
Finish(i)= = false;
Need i ≤work;
如找到则执行步骤3;否则,执行步骤4;

3. 当进程Pi获得资源后,可顺利执行直到完成,并释放出分配给它的资源,故应执行
Work = work + Allocation i
Finish(i)=true;转向步骤2;

4. 若所有进程的Finish(i)都为true,则表示系统处于安全状态;否则,系统处于不安全状态。

②实验要求
设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。
系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析;

3.流程图与模块调用

操作系统 进程调度-银行家算法实验报告_资源分配_02

4.实验分析

想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。
在我的理解中,

银行家算法的思想:

银行家算法让进程动态地申请资源,系统在每次实施资源分配之前,先计算资源分配的安全性,即分配完是否会进入不安全状态。
若此次资源分配安全,便将资源分配给进程,否则不分配资源,让进程等待。

银行家算法的理解:

操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。

当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。

若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。

5.运行情况

操作系统 进程调度-银行家算法实验报告_资源分配_03

6.实验体会

通过本次实验,我深刻的理解了操作系统中线程资源的分配方式和银行家算法。操作系统实验重在理解每一个算法的意图和目的,那么就选择适当的数据结构模拟过程就可以完成相关算法了。

系统有多个种资源并且每一种资源的数目有限,有多个想要申请这些资源的进程,僧多粥少,所以要好好安排分配的顺序,不然就会导致不安全状态甚至死锁。

本次实验采用python完成,IDE是pycharm。

【附】实验代码

import numpy as np


def security(work, need, allocation):
n = need.shape[0]
finish = np.array([False] * n, dtype=bool)
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, n):
print("--------------------------")
print("进程\t最大需求量\t已分配量\t剩余需要分配量")
for i in range(n):
print("P{}\t\t{}\t\t{}\t\t{}".format(
i, max_table[i], allocation[i], need[i]))
print("当前剩余资源:", available)


if __name__ == '__main__':

m = int(input("输入资源种类数 m: "))

temp = input("输入进程数资源,空格隔开:").split()
available = np.array(temp, dtype=int) # 可利用资源向量

n = int(input("输入进程数 n: "))
max_table = np.zeros([n, m], dtype=int) # 最大需求矩阵
allocation = np.zeros([n, m], dtype=int) # 分配矩阵

# 输入最大需求资源
for i in range(n):
temp = input("输入进程 P{} 的最大需求向量:".format(i)).split()
max_table[i] = np.array(temp, dtype=int)

if (available < max_table[i]).any():
print("输入有误,重新输入")
i -= 1
# 输入已分配资源
for i in range(n):
temp = input("输入进程 P{} 的已分配资源:".format(i)).split()
allocation[i] = np.array(temp, dtype=int)

if (max_table[i] < allocation[i]).any():
print("输入有误,重新输入")
i -= 1

need = max_table - allocation # 剩余需求矩阵

# 计算剩余资源
for i in allocation:
available -= i

printTable(available, max_table, allocation, need, n)

while (need != 0).any():
proc_ind, req = input("输入接下来的请求: ").split(',')
proc_ind = int(proc_ind[1:])
req = np.array(req.split(), dtype=int)

# 判断合法性
if (req > max_table[proc_ind]).any():
print("输入有误,重新输入")

# 判断安全性
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("不安全,不能分配")
available += req
allocation[proc_ind] -= req
need[proc_ind] += req