【实验目的】
为了了解系统的资源分配情况,假定系统的任何一种资源在任意时刻只能被一个进程使用,任何进程已经占用的资源只能由进程自己释放,而不能由其他进程抢占,当进程申请的资源不能满足时,必须等待。因此只要资源分配算法能保证进程的资源请求,且不出现循环等待,则系统不会出现死锁。
要求编写系统进行资源调度的程序。一个是随机动态地进行资源分配的模拟程序,即只要系统当前剩余资源满足进程的当前要求,就立即将资源分配给进程,以观察思索产生情况;一个是采用银行家算法,有效地避免死锁的产生。
【实验原理】
- 银行家算法。
银行家算法是从当前状态出发,按照系统各类资源剩余量逐个检查各进程需要申请的资源量,找到一个各类资源申请量均小于等于系统剩余资源量的进程P1。然后分配给该P1进程所请求的资源,假定P1完成工作后归还其占有的所有资源,更新系统剩余资源状态并且移除进程列表中的P1,进而检查下一个能完成工作的进程。如果所有进程都能完成工作,则找到一个安全序列,当前状态是安全的。则当前状态不安全。 - 安全性算法
(1) 设置两个向量:
① 工作向量 Work:它表示系统可提供给进程继续运行所需的各类资源数量的多少,它含有m个元素,在执行安全算法开始时,Work = Available;
② Finish:它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]= false;当有足够资源分配给进程时, 再令Finish[i]= true。
(2) 从进程集合中找到一个能满足下述条件的进程:
① Finish[i]= false;
② Need[i,j]≤ Work[j];
如果找到,那么,执行步骤(3);否则,执行步骤(4)。
(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]= Work[i]+Allocation[i,j];
Finish[i]= true;
go to step 2;
(4) 如果所有进程的Finish[i]= true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。
【实验内容】
- 要求
(1) 设计3-4个并发进程,共享系统的10个同类不可抢占的资源。各进程动态进行资源的申请和释放。
(2) 用银行家算法和随机算法分别设计一个资源分配程序,运行整两个程序,观察系统运行情况,并对系统运行的每一步情况进行显示。 - 实验代码
//用银行家算法和随机算法实现资源分配
#include <iostream>
#include<string>
using namespace std;
#define MAXNUM 10
#define WAITING 0 // 表示进程正在等待
#define FINISHED 1 // 表示进程已完成
#define NONE -1 // 表示当前请求资源的进程数为0
int Available = 10; // 10个同类不可抢占的资源
class pcb // 进程控制块
{
public:
pcb(); // 构造函数
friend void AllocationTalbe(pcb Queue[], int length);// 打印资源分配表
friend void Bankers(pcb Queue[], int length); // 银行家算法
friend void ShowSeries(pcb Queue[], int length); // 打印安全序列
friend void Security(pcb Queue[], int length); // 安全性算法
private:
string name; // 进程名
int status; // 状态
int max; // 资源需求总量
int allocation;// 已占资源量
int need; // 仍需资源量
bool finish; // 能执行完标志
};
pcb::pcb() // 构造函数,初始化进程控制块
{
cout << "Process name: ";
cin >> name; // 输入进程名
cout << "Process MAX Require: ";
cin >> max; // 输入资源需求总量
cout << "Process allocation: ";
cin >> allocation; // 输入已分配资源量
Available -= allocation; // 可用资源量减少
need = max - allocation;// 仍需要的资源量
cout << "Process still need: " << need;
cout << endl << endl;
status = WAITING; // 进程初始化为等待 状态
finish = false; // 初始化为未执行状态
}
void AllocationTalbe(pcb Queue[], int length)
{
cout << "Resource allocation table:" << endl << endl; // 打印资源分配情况
cout << "┏ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓" << endl;
cout << "┃ Max Allocation Need Available┃" << endl;
for (int i = 0; i < length; i++) {
cout << "┃ " << Queue[i].name << " " << Queue[i].max << " "
<< Queue[i].allocation << " " << Queue[i].need << " ";
if (i == 0) {
cout << Available;
}
cout<< "\t ┃" << endl;
}
cout << "┗ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛" << endl;
}
void Security(pcb Queue[], int length); // 安全性算法
void Bankers(pcb Queue[], int length) // 银行家算法
{
// 提示输入请求资源的进程号,没有则输入4
cout << endl;
cout << "Which process has a request?" << endl;
cout << "Enter the number of process(0-3), if none then enter '-1'" << endl;
cout << ">> ";
int num;
cin >> num;
if (num == NONE) { // 没有进程提出新的请求时,资源分配情况不变
cout << "The resource allocation table has no change!" << endl;
}
else {
cout << Queue[num].name << " requests: ";
int request;
cin >> request; // 输入当前请求量
if (request > Queue[num].need) { // 检查是否超过需求量
cout << "The process's request can't bigger than process's need!" << endl;
system("pause");
exit(-1);
}
else {
if (request > Available) { // 检查是否有足够的资源
cout << "The available resource is not enough!";
system("pause");
exit(-1);
}
else { // 尝试将资源分配给进程
Available -= request;
Queue[num].allocation += request;
Queue[num].need -= request;
AllocationTalbe(Queue, length);// 打印新的资源分配表
}
}
}
Security(Queue, length); //用安全性算法检验
}
int Work[MAXNUM] = { 0 };// 工作向量
int Snum[MAXNUM] = { 0 };// 安全序列中的进程序号
void ShowSeries(pcb Queue[], int length) // 打印安全序列
{
cout << endl;
cout << "┏ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓" << endl;
cout << "┃ Work Need Allocation Work+Allocation Finish┃" << endl;
for (int i = 0; i < length; i++) {
if (Queue[Snum[i]].finish) {
cout << "┃ " << Queue[Snum[i]].name << " " << Work[i] << " "
<< Queue[Snum[i]].need << " " << Queue[Snum[i]].allocation << " "
<< Work[i + 1] << "\t\t\t" << "T ┃" << endl;
}
}
cout << "┗ 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛" << endl;
cout << endl << endl;
}
void Security(pcb Queue[], int length) // 安全性算法
{
int i = 0, j = 0, k = 0;
Work[i] = Available; // Work向量初值为Available的值
for (j = 0; j < length; j++) {
for (k = 0; k < length; k++) {
if ((Queue[k].finish == false) && (Queue[k].need <= Work[i]))
{
Work[i + 1] = Work[i] + Queue[k].allocation;
Queue[k].finish = true;
Snum[i++] = k; // 记录安全队列中进程编号
}
}
}
int finish=1;
for (j = 0; j < length; j++) {
if (Queue[j].finish == false) { // 无法形成安全队列
finish = 0;
cout << endl;
cout << "Can't get a security series, this moment is not safe!" << endl;
ShowSeries(Queue, length); // 打印安全队列
system("pause");
exit(-1);
}
}
if (finish == 1) {
cout << endl;
cout << "Security series: ";
for (int i = 0; i < length; i++) {
cout << Queue[Snum[i]].name << " ";
}
}
ShowSeries(Queue, length); // 打印安全队列
}
int main()
{
pcb *que = new pcb[4]; // 定义四个进程
AllocationTalbe(que, 4);// 显示储时资源分配情况
system("cls");
Bankers(que, 4); // 银行家算法进行调度
return 0;
}
【运行结果】
- 先创建四个进程p0, p1, p2, p3
- 根据提示做出选择,有进程提出request则输入进程编号,没有则输入-1,一下几组测试所用数据相同,不重复截图。
- 没有进程提出request时,经过检验可形成安全序列p1 p3 p0 p2,所以初始状态是安全的。
- 当p3提出request为1时,尝试将资源分配给它,此时能形成安全序列p1 p3 p0 p2,所以分配给p3是安全的。
- 当p0提出request为1时,尝试将资源分配给它,若进行分配则只能满足p1进程,无法形成安全序列。故不能分配。