多级反馈队列算法
问题简介
在操作系统中,多进程运行的次序是不一样的,这种时候就需要选择执行的顺序。
在分时系统中多采用循环轮转调度算法,系统规定一个时间片,每个进程被调度的时候分得一个时间片,当这一时间片用完时,
该进程转为就绪态并进入就绪队列末尾。这就是循环轮转算法的主要思路。
(下面的代码只考虑P1-----P5的进程)
简单循环轮转调度
当CPU空闲时,选取就绪队列首元素,赋予时间片。当进程时间片用完时,就释放CPU控制权,进入就绪队列末尾,CPU控制权给
下一个处于就绪队列首元素。
状态图如下:
具体思路
本来想用队列来算的,但是考虑到指针的问题,又因为刚学了循环链表,所以考虑用循环链表来存放数据。
(循环列表和一般链表唯一一个区别就是最后一个结点本来是p->next=NULL,现在就把头结点和尾结点相连就行,即p->next=head)
下面是结构体的里面的内容,放入进程的名字以及需要运行的时间和等待时间
struct pcb { char name[10]; //进程名称 int need, turn; //进程运行时间和已等待时间 struct pcb *next; };
然后,给链表赋初值
//给队列1 赋值 struct pcb *create1() { int num(0); struct pcb *rq1 = NULL; struct pcb *p = NULL; struct pcb *t;//head头结点 p当前结点 t下一结点 struct pcb *next; while(num<len1) { t = (struct pcb*)malloc(sizeof(struct pcb)); if (num == 0) { rq1 = t; p = t; } else if (num == len1 - 1) { p->next = t; p = t; t->next = rq1; } else { p->next = t; p = t; t->next = NULL; } init(t); ++num; } return rq1; } void init(struct pcb*p) { cin >> p->name >> p->need >> p->turn; }
在计算运行时间的时候,
1.比如说第一个进程的运行时间小于或等于时间片的长度,所以,就把时间加上去,并将每个进程的等待时间都加上这个进程的运行时间。
并且将正在运行的进程的need赋值为0。这样是为了将need标记为已经运行完的了,以后若再碰到就跳过这个结点。
2.再比如说第一个进程的运行时间大于时间片的长度,就将该进程的need减去一个时间片的长度,并且将指针移到下个结点,相当于把这个结点放到队列尾部。
再把各个进程的等待时间加上一个时间片的长度。就这样反复的循环,知道所有结点的need全部变为0的时候就跳出来。
直接上代码吧:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
//#define NULL 0
#include<queue>
using namespace std;
const int maxn = 100;
struct pcb {
char name[10]; //进程名称
int need, turn; //进程运行时间和已等待时间
struct pcb *next;
};
int len1(0), len2(0); //两个进程的长度
int clock(0); //时钟
int time(0);//时间片大小
int TIME; //rq1运行完的时间
void init(struct pcb*p) {
cin >> p->name >> p->need >> p->turn;
}
//给队列1 赋值
struct pcb *create1() {
int num(0);
struct pcb *rq1 = NULL;
struct pcb *p = NULL;
struct pcb *t;//head头结点 p当前结点 t下一结点
struct pcb *next;
while(num<len1) {
t = (struct pcb*)malloc(sizeof(struct pcb));
if (num == 0) {
rq1 = t;
p = t;
}
else if (num == len1 - 1) {
p->next = t;
p = t;
t->next = rq1;
}
else {
p->next = t;
p = t;
t->next = NULL;
}
init(t);
++num;
}
return rq1;
}
//当运行时间小于时间片大小时候的求和函数,即将每个进程的等待时间加上当前进程运行的时间
void sum1(struct pcb *p) {
struct pcb *t;
t = p;
while (p->next != t) {
if (p->need != 0) {
p->turn += t->need;
p = p->next;
}
else p = p->next;;
}
p->turn += t->need;
}
//当运行时间大于时间片大小时候的求和函数,即将每个进程的等待时间加上当前进程运行的时间
void sum2(struct pcb *p) {
struct pcb *t;
t = p;
while (p->next != t) {
if (p->need != 0) {
p->turn += time;
p = p->next;
}
else p=p->next;
}
p->turn += time;
}
//求队列1里面各个进程运行完毕需要花费的时间
void fun1(struct pcb *h) {
int num, count;
while (1) { //最后一个的next ==NULL
num = 0;
count = len1;
struct pcb *t = h; //将h赋给t
if (t->need <= time && t->need != 0) { //如果这个进程运行时间小于时间片且非零说明没有弄完
clock += t->need;
sum1(t);
h->need = 0;
cout << h->name << "的运行时间是" << h->turn << endl;
}
if(t->need>time) {
clock += time;
t->need -= time;
sum2(t);
}
h = h->next;
struct pcb *temp = h;
while (count--) {
if (temp->need == 0) {
num++;
}
temp = temp->next;
}
if (num == 4) break;
}
while (h->need == 0) {
h = h->next;
}
while (h->need>time) {
h->need -= time;
h->turn += time;
}
// return (h->turn + h->need);
TIME = h->turn + h->need;
cout<<h->name<<"的运行时间是 "<< h->turn + h->need << endl;
// cout << h->turn + h->need << endl;
}
int main() {
cout << "请输入时间片大小:";
cin >> time;
cout << endl;
cout << "请输入进程1和进程2的数量:";
cin >> len1 >> len2;
cout << endl;
struct pcb *rq1, *rq2;
cout << "请输入进程1的信息:" << endl;
rq1 = create1();
cout << "请输入进程2的信息:" << endl;
rq2 = create2();
/* cout << "遍历进程1的信息:" << endl;
see1(rq1);
cout << "遍历进程2的信息:" << endl;
see2(rq2);
sort(rq2);
cout << "排序后进程2的信息:" << endl;
see2(rq2);*/
cout << "队列rq1运行完毕,花费的时间为:" << endl;;
fun1(rq1);
cout << endl;
cout << "队列rq2运行完毕,花费的时间为:" << endl;
fun2(rq2);
cout << endl;
return 0;
}
运行结果:
!!!!!!说一个令人自闭的事!!!!!!
这个程序我调了好久,经常因为死循环的问题,输出不出来结果,真的快自闭了。。。
从开始打断点慢慢调试的时候,找到卡住死循环的位置,慢慢改,终于改好了。
还是要有耐心啊!!!