Hello!友友们好,我是薛定谔怀里的猫,操作系统是我在大三上学期学习的专业课,利用假期时间我把我的实验报告整理了出来,作为自己的学习记录和复习资料。这是实验报告二,其余的可以点开我头像看嗷!完整的代码放在了资源下载处,有需要的友友们可以自行下载嗷~~另外我还会整理C语言、数据结构、数据库原理、编译原理、数字逻辑等的实验报告,还有本人的一些期末大作业~欢迎可爱的你来光临我的小天地!
实验目的
通过本实验,进一步掌握进程调度的功能和实现原理。
实验环境
1、硬件:pc 机及其兼容机。
2、软件:Windows OS,Dev-C++(C语言)。
实验内容
1、 设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度算法等。
2、 进程调度功能作为一个函数 scheduler,加入到实验题目一中。
3、 进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”的提示信息。
4、 若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执行。若运行完,应删除相应 PCB。
算法设计
算法1:void main() //主函数,显示进程调度算法选择菜单
输入:无
输出:无
1、flag<-1
2、while(flag==1) do
3、 打印系统调度算法菜单;
4、 接收用户输入的选项method
5、 switch(method):
6、 case 1:
7、 case 2:
8、 case 3: 调用fmenu函数;break;
9、 case 0:flag<-0;break;
10、 default:提示输入错误;
11、 end switch
12、end while
算法2:void fmenu(int method) //菜单函数,显示操作菜单
输入:进程调度算法按钮
输出:无
1、创建就绪、运行、阻塞三个队列链表的头结点
2、flag<-1;
3、while(flag==1) do
4、 打印菜单,接收用户的输入选项
5、 switch(choice):
5、 case 1~3:根据用户的输入调用相关函数;
6、 case 0:flag<-0;
7、 default: 提示用户输入无效;
8、 end switch
9、end while
算法3:int findList(PCB L,char name[]) //查找输入的进程名在某队列中是否存在
输入:ready\run\block中某个队列;进程名
输出:1/0,1代表在队列中,0代表不在
1、p<-L->next;
2、for(;p!=NULL;p<-p->next) do
3、 if(strcmp(p->pname,name)==0) then //发现输入name与该
4、 return 1; 队列中某进程名相同,返回1,否则返回0
5、 end if
6、end for
7、return 0;
算法4:void fcreate(PCB ready,PCB run,PCB block,int method)//创建进程
输入:ready、run、block三个队列,进程调度算法按钮
输出:无
1、number++; //设置全局变量记录进程总数量
2、if(number>10) then
3、 提示进程数超过10,不允许再创建
4、else
5、 while(flag==1) do
6、 输入新的进程名;
7、 op<-1;
8、 while(op==1) do
9、 if(该进程名已经存在) then
10、 提示用户重新输入;
11、 else
12、 op<-0;
13、 end if
14、 end while
15、 尾插法创建一个新的进程放入就绪队列末尾;
16、 输入是否需要再创建一个新进程,是:flag<-1;否:flag<-0;
17、 end while
18、end if
算法5:void frun(PCB ready,PCB run,int method) //实现进程切换
输入:ready、run两个队列,进程调度算法按钮
输出:无
1、flag<-1;
2、if(ready->next==NULL) then
3、 提示就绪队列为空,无法再调进程运行;
4、else
5、 while(flag==1) do
6、 switch(method)
7、 case 1:fprior(ready,run);break; //高优先权优先调度算法
8、 case 2:ftimeschedule(ready,run);break; //时间片轮转调度算法
9、 case 3:ftime(ready,run);break; //短进程优先调度算法
10、 end switch
11、 if(method==1 or method==3) then
12、 输入是否要进程切换,是:flag<-1;否:flag<-0;
13、 if(flag==1) then
14、 如判断就绪队列为空,则提示无法再调进程运行;break;
15、 else if(method==2) then
16、 提示所有进程已经执行完毕!就绪队列为空;
17、 end while
18、end if
算法6:void fprior(PCB ready,PCB run) //高优先权优先调度算法
输入:ready、run队列
输出:无
1、删除run队列中正在运行的进程
2、q<-ready->next;
3、leve<-ready->next->level; //将就绪队列首个进程的优先级赋给leve
4、while(q) do
5、 if(q节点的优先级数字小于leve) then
6、 leve<-q节点优先级
7、 让r指针指向q节点
8、 q<-q->next
9、 else
10、 q<-q->next
11、 end if
12、end while
13、最终r指针指向优先级最高的节点,将该节点从就绪队列取出
14、将r节点插入运行队列中
15、显示当前正在运行的进程信息
算法7:void ftimeschedule(PCB ready,PCB run) //时间片轮转调度算法
1、输入系统时间片
2、while(ready->next) do
3、 对当前就绪队列中的进程进行计数,为count
4、 for(i=1;i<=count;i++) do
5、 拿下就绪队列的第一个节点,修改状态为运行态
6、 将节点插入到运行队列中;
7、 if((该运行进程的需要时间-时间片)>0) then
8、 将该与运行进程的剩余时间-时间片后,从运行队列取出
9、 将其插入就绪队列末尾
10、 else
11、 直接将该运行进程从运行队列删去
12、 end if
13、 end for
14、 遍历就绪队列,打印出所有进程的信息:进程名和剩余时间
15、 按任意键继续;
16、end while
算法8:void ftime(PCB ready,PCB run) //高优先权优先调度算法
输入:ready、run队列
输出:无
1、删除run队列中正在运行的进程
2、q<-ready->next;
3、time<-ready->next->runtime; //将就绪队列首个进程的运行时间赋给time
4、while(q) do
5、 if(q节点的运行时间小于time) then
6、 time<-q节点运行时间
7、 让r指针指向q节点
8、 q<-q->next
9、 else
10、 q<-q->next
11、 end if
12、end while
13、最终r指针指向运行时间最短的节点,将该节点从就绪队列取出
14、将r节点插入运行队列中
15、显示当前正在运行的进程信息
完整代码
详见资源下载处
运行结果
1、测试高优先权优先调度算法:创建p1、p2、p3、p4四个进程,优先级分别为4、1、3、2。接下来开始进程调度,按照优先级由高到低,系统会依次调入p2、p4、p3、p1运行,并且每次调入新进程时,都会将当前正在运行的进程终止。
最后系统中只有最后一个优先级最低的进程p1在运行队列中。如下图:
2、测试时间片轮转调度算法。创建p1、p2、p3、p4四个进程,运行时间分别为9、5、8、1,设置时间片为2。接下来开始进程调度,每一次时间片轮转完毕,都显示出当前就绪队列中还未执行完毕的进程及其剩余时间。最后所有的进程都会执行完毕,就绪队列为空。
3、测试短进程优先调度算法:创建p1、p2、p3、p4四个进程,运行时间分别为10、1、2、8。接下来开始进程调度,按照运行时间由短到长,系统会依次调入p2、p3、p4、p1运行,并且每次调入新进程时,都会将当前正在运行的进程终止。
最后系统中只有最后一个运行时间最长的进程p1在运行队列中。
实验总结
问题1:
本次实验的代码是在实验1的基础上写的,但是函数有改变,因此在编写时要理清楚本次实验的代码与上次实验代码的差异,不能照搬。
*解决方法:*感觉不能着急上手写代码,还是要认真读实验书的内容以及老师发的材料,把各种关系、原理,理得比较清楚了再写。
问题2:
本次实验的进程调度算法都是静态的,也就是所有的进程都创建完后,再根据算法进行调度。
*解决方法:*实验1的frun函数是一开始第一个进程创建完后,就把它调入运行队列运行,在本次实验中不用考虑这个问题,应该先创建出所有进程,再进行调度。
问题3:
在时间片轮转调度算法中,因为每一轮时间片运行时,未运行结束的进程都要回到就绪队列末尾,那么,如何区分就绪队列中,从哪个进程开始属于是下一轮的呢?
*解决方法:*最开始想的是每一轮开始前,先用一个指针指向就绪队列末尾,作为指示一轮进程的最后一个进程的标志,但是这样做,循环的条件并不好设置。比如,r指针指向一轮的末尾进程,循环结束的标志,无论是ready->next!=r还是ready->next==r都是不合适的,考虑起来很麻烦。
因此,后来想到可以在每一轮新的时间片轮转开始之前,先对就绪队列中的所有进程,也就是同一轮时间片轮转的进程进行计数,这样循环就能方便实现了。
思考4:
短进程优先调度算法和高优先权优先调度算法的代码基本一致,高优先权优先调度算法是每一次选择就绪队列中优先权最高的,短进程优先调度算法则是每一次选择就绪队列中运行时间最短的。所以写完了高优先权优先调度算法的代码,可以直接将找最高优先权部分变为找最短运行时间,这样短进程优先调度算法的代码可以很快得到。