-------------------------------脑瓜疼脑瓜疼,哎呀妈呀脑瓜疼------------------------
多级反馈队列算法
问题简介
在操作系统中,多进程运行的次序是不一样的,这种时候就需要选择执行的顺序。
在分时系统中多采用循环轮转调度算法,系统规定一个时间片,每个进程被调度的时候分得一个时间片,当这一时间片用完时,
该进程转为就绪态并进入就绪队列末尾。这就是循环轮转算法的主要思路。
(下面的代码只考虑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; }
运行结果:
!!!!!!说一个令人自闭的事!!!!!!
这个程序我调了好久,经常因为死循环的问题,输出不出来结果,真的快自闭了。。。
从开始打断点慢慢调试的时候,找到卡住死循环的位置,慢慢改,终于改好了。
还是要有耐心啊!!!
不早啦,早点睡觉吧!晚安!