操作系统资源预分配算法 银行家算法C++模拟 banker_algorithm.cpp
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <windows.h>
#include <cstring>
#include <iostream>
using namespace std;
#define WAIT 0
#define READY 1
#define RUN 2
#define DESTROY 3
struct Res {
int a, b, c, d;
Res() {}
Res(int a_, int b_, int c_, int d_):a(a_), b(b_), c(c_), d(d_) {}
bool operator > (Res &res) {
if (a > res.a && b > res.b && c > res.c && d > res.d) return true;
return false;
}
Res operator + (Res &res) {
return Res(a + res.a, b + res.b, c + res.c, d + res.d);
}
Res operator - (Res &res) {
return Res(a - res.a, b - res.b, c - res.c, d - res.d);
}
Res& operator += (Res &res) {
a += res.a;
b += res.b;
c += res.c;
d += res.d;
return *this;
}
Res& operator -= (Res &res) {
a -= res.a;
b -= res.b;
c -= res.c;
d -= res.d;
return *this;
}
Res& operator = (Res &res) {
a = res.a;
b = res.b;
c = res.c;
d = res.d;
return *this;
}
};
struct Node {
int pid; // 进程程的PID号,用来代替进程名
struct Res max; // 该进程所需的各类资源的最大数量(Max向量)
struct Res alloc; // 该进程已分配的各类资源数量(Allocation向量)
struct Res req; // 该进程当前请求的各资源数量(Request向量)
int status; // 表示进程的状态 0-等待 1-就绪 2-运行 3-销毁
};
struct Res maxr; // 各类资源的最大数量(Max向量)
struct Res alloc; // 分配的各类资源数量(Allocation向量)
typedef struct Node Process;
queue<Process*> ready;
queue<Process*> wait;
Process* list[100]; // 系统进程表
inline void init() {
while (!ready.empty()) ready.pop();
while (!wait.empty()) wait.pop();
maxr.a = rand() % 100 + 65;
maxr.b = rand() % 100 + 65;
maxr.c = rand() % 100 + 65;
maxr.d = rand() % 100 + 65;
alloc.a = 0;
alloc.b = 0;
alloc.c = 0;
alloc.d = 0;
}
Process* create(int pid) {
Process* p = (Process*)malloc(sizeof(Process));
p->pid = pid;
// 最大分配资源量较大
p->max.a = rand() % 30 + 15;
p->max.b = rand() % 30 + 15;
p->max.c = rand() % 30 + 15;
p->max.d = rand() % 30 + 15;
// 初始时候分配资源为0
p->alloc.a = 0;
p->alloc.b = 0;
p->alloc.c = 0;
p->alloc.d = 0;
// 每次请求分配的资源数量
p->req.a = rand() % 15 + 1;
p->req.b = rand() % 15 + 1;
p->req.c = rand() % 15 + 1;
p->req.d = rand() % 15 + 1;
p->status = WAIT; // 设置为等待状态
return p;
}
void display_res(Res &res) {
printf("%4d %4d %4d %4d ", res.a, res.b, res.c, res.d);
}
void display_head() {
printf(" ");
printf(" Max Resources ");
printf(" Alloc Resources ");
printf(" Req Resources ");
printf("\n");
printf(" PID");
for (int i=0; i<3; i++) {
printf(" A B C D ");
}
printf(" Status");
printf("\n");
}
void display_body(Process* p) {
// if (p->status == DESTROY) return;
printf("%4d", p->pid);
display_res(p->max);
display_res(p->alloc);
display_res(p->req);
int status = p->status;
// 进程的状态 0-等待 1-就绪 2-运行
if (status == 0) printf(" Wait");
if (status == 1) printf(" Ready");
if (status == 2) printf(" Run");
if (status == 3) printf("Destroy");
printf("\n");
}
void display_queue(queue<Process*> q) {
queue<Process*> tmp;
while (!tmp.empty()) tmp.pop();
while (!q.empty()) {
Process* head = q.front();
q.pop();
printf("%d ", head->pid);
tmp.push(head);
}
q = tmp;
printf("\n");
}
void display(int n) {
display_head();
for (int i=0; i<n; i++) {
display_body(list[i]);
}
printf(" All");
display_res(maxr);
display_res(alloc);
printf("\n\n");
printf("Ready Queue: "); display_queue(ready);
printf(" Wait Queue: "); display_queue(wait);
}
bool check(Res &res) {
queue<Process*> q;
while (!q.empty()) q.pop();
bool flag = false;
while (!ready.empty()) {
Process* p = ready.front(); ready.pop(); q.push(p);
Res need = p->max - p->alloc;
if (res > need) flag = true;
}
ready = q;
return flag;
}
void schedule() {
// 银行家算法
// 如果两个队列都为空, 说明所有进程已销毁
if (ready.empty() && wait.empty()) return;
// 如果就绪队列空,发生队列复制
Process* tmp;
if (ready.empty()) {
while (!wait.empty()) {
tmp = wait.front(); // 取得第一个元素
tmp->status = READY;
ready.push(tmp); // 插入就绪队列队尾
wait.pop(); // 删除等待队列队首
}
return; // 去掉return认为复制队列没有开销
}
tmp = ready.front();
Res need = tmp->alloc + tmp->req; // 计算进程所需资源
if (tmp->max > need) {
// 计算所剩资源
Res left = maxr - alloc - tmp->req;
display_res(left); cout << endl;
// 检查系统是否安全
if (check(left)) {
tmp->alloc += tmp->req;
alloc += tmp->req;
tmp->status = RUN;
} else {
tmp->status = WAIT;
}
wait.push(tmp);
} else {
alloc.a -= (tmp->alloc).a; // 回收资源
alloc.b -= (tmp->alloc).b; // 回收资源
alloc.c -= (tmp->alloc).c; // 回收资源
alloc.d -= (tmp->alloc).d; // 回收资源
tmp->alloc.a = 0; tmp->alloc.b = 0; tmp->alloc.c = 0; tmp->alloc.d = 0;
tmp->status = DESTROY; // 销毁进程
}
ready.pop();
}
int main()
{
init();
int n; n = 20; // cin >> n;
// 0号进程是init进程
for (int i=1; i<=n; i++) {
Process* p = create(i);
wait.push(p);
list[i-1] = p;
}
while (!ready.empty() || !wait.empty()) {
display(n);
Sleep(1000);
schedule();
system("cls");
}
printf("All task is done!");
return 0;
}