-------------------------------脑瓜疼脑瓜疼,哎呀妈呀脑瓜疼------------------------
多级反馈队列算法
问题简介
在操作系统中,多进程运行的次序是不一样的,这种时候就需要选择执行的顺序。
在分时系统中多采用循环轮转调度算法,系统规定一个时间片,每个进程被调度的时候分得一个时间片,当这一时间片用完时,
该进程转为就绪态并进入就绪队列末尾。这就是循环轮转算法的主要思路。
(下面的代码只考虑P1-----P5的进程)
简单循环轮转调度
当CPU空闲时,选取就绪队列首元素,赋予时间片。当进程时间片用完时,就释放CPU控制权,进入就绪队列末尾,CPU控制权给
下一个处于就绪队列首元素。
状态图如下:
具体思路
本来想用队列来算的,但是考虑到指针的问题,又因为刚学了循环链表,所以考虑用循环链表来存放数据。
(循环列表和一般链表唯一一个区别就是最后一个结点本来是p->next=NULL,现在就把头结点和尾结点相连就行,即p->next=head)
下面是结构体的里面的内容,放入进程的名字以及需要运行的时间和等待时间
structpcb {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
t= (struct pcb*)malloc(sizeof(structpcb));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;
}returnrq1;
}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#include#include
//#define NULL 0
#include
using namespacestd;const int maxn = 100;structpcb {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
t= (struct pcb*)malloc(sizeof(structpcb));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;
}returnrq1;
}//当运行时间小于时间片大小时候的求和函数,即将每个进程的等待时间加上当前进程运行的时间
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) {intnum, 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 <
}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<name<turn + h->need <turn + h->need << endl;
}intmain() {
cout<< "请输入时间片大小:";
cin>>time;
cout<
cout<< "请输入进程1和进程2的数量:";
cin>> len1 >>len2;
cout<
cout<< "请输入进程1的信息:" <
rq1=create1();
cout<< "请输入进程2的信息:" <
rq2=create2();/*cout << "遍历进程1的信息:" << endl;
see1(rq1);
cout << "遍历进程2的信息:" << endl;
see2(rq2);
sort(rq2);
cout << "排序后进程2的信息:" << endl;
see2(rq2);*/cout<< "队列rq1运行完毕,花费的时间为:" <
fun1(rq1);
cout<
cout<< "队列rq2运行完毕,花费的时间为:" <
fun2(rq2);
cout<
}
运行结果:
!!!!!!说一个令人自闭的事!!!!!!
这个程序我调了好久,经常因为死循环的问题,输出不出来结果,真的快自闭了。。。
从开始打断点慢慢调试的时候,找到卡住死循环的位置,慢慢改,终于改好了。
还是要有耐心啊!!!
不早啦,早点睡觉吧!晚安!