操作系统实验二:模拟进程调度功能

Hello!友友们好,我是薛定谔怀里的猫,操作系统是我在大三上学期学习的专业课,利用假期时间我把我的实验报告整理了出来,作为自己的学习记录和复习资料。这是实验报告二,其余的可以点开我头像看嗷!完整的代码放在了资源下载处,有需要的友友们可以自行下载嗷~~另外我还会整理C语言、数据结构、数据库原理、编译原理、数字逻辑等的实验报告,还有本人的一些期末大作业~欢迎可爱的你来光临我的小天地!

实验目的

通过本实验,进一步掌握进程调度的功能和实现原理。

实验环境

1、硬件:pc 机及其兼容机。
2、软件:Windows OS,Dev-C++(C语言)。

实验内容

1、 设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度算法等。
2、 进程调度功能作为一个函数 scheduler,加入到实验题目一中。
3、 进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”的提示信息。
4、 若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执行。若运行完,应删除相应 PCB。

算法设计

算法1void main()  //主函数,显示进程调度算法选择菜单
输入:无
输出:无
1、flag<-1
2while(flag==1) do
3、    打印系统调度算法菜单;
4、    接收用户输入的选项method
5switch(method)6case 1:
7case 2:
8case 3: 调用fmenu函数;break9case 0:flag<-0;break10default:提示输入错误;
11、   end switch
12、end while

算法2void fmenu(int method)  //菜单函数,显示操作菜单
输入:进程调度算法按钮
输出:无
1、创建就绪、运行、阻塞三个队列链表的头结点
2、flag<-1;
3while(flag==1) do
4、    打印菜单,接收用户的输入选项
5switch(choice):
5case 1~3:根据用户的输入调用相关函数;
6case 0:flag<-0;
7default: 提示用户输入无效;
8、    end switch
9、end while

算法3int findList(PCB L,char name[])  //查找输入的进程名在某队列中是否存在
输入:ready\run\block中某个队列;进程名
输出:1/01代表在队列中,0代表不在
1、p<-L->next;
2for(;p!=NULL;p<-p->next) do
3if(strcmp(p->pname,name)==0) then  //发现输入name与该
4return 1;                   队列中某进程名相同,返回1,否则返回0
5、    end if
6、end for
7return 0;

算法4void fcreate(PCB ready,PCB run,PCB block,int method)//创建进程
输入:ready、run、block三个队列,进程调度算法按钮
输出:无
1、number++//设置全局变量记录进程总数量
2if(number>10) then
3、    提示进程数超过10,不允许再创建
4else
5while(flag==1) do
6、        输入新的进程名;
7、        op<-1;
8while(op==1) do
9if(该进程名已经存在) then
10、                提示用户重新输入;
11else
12、               op<-0;
13、           end if
14、        end while
15、        尾插法创建一个新的进程放入就绪队列末尾;
16、        输入是否需要再创建一个新进程,是:flag<-1;否:flag<-017、    end while
18、end if

算法5void frun(PCB ready,PCB run,int method) //实现进程切换
输入:ready、run两个队列,进程调度算法按钮
输出:无                                  
1、flag<-1;
2if(ready->next==NULL) then
3、    提示就绪队列为空,无法再调进程运行;
4else
5while(flag==1) do
6switch(method)
7case 1:fprior(ready,run);break;   //高优先权优先调度算法
8case 2:ftimeschedule(ready,run);break; //时间片轮转调度算法
9case 3:ftime(ready,run);break;    //短进程优先调度算法
10、       end switch
11if(method==1 or method==3) then
12、            输入是否要进程切换,是:flag<-1;否:flag<-013if(flag==1) then
14、                如判断就绪队列为空,则提示无法再调进程运行;break;
15else if(method==2) then
16、            提示所有进程已经执行完毕!就绪队列为空;
17、    end while
18、end if

算法6void fprior(PCB ready,PCB run)  //高优先权优先调度算法
输入:ready、run队列
输出:无
1、删除run队列中正在运行的进程
2、q<-ready->next;
3、leve<-ready->next->level;         //将就绪队列首个进程的优先级赋给leve
4while(q) do
5if(q节点的优先级数字小于leve) then
6、        leve<-q节点优先级
7、        让r指针指向q节点
8、        q<-q->next
9else 
10、       q<-q->next
11、   end if
12、end while
13、最终r指针指向优先级最高的节点,将该节点从就绪队列取出
14、将r节点插入运行队列中
15、显示当前正在运行的进程信息

算法7void ftimeschedule(PCB ready,PCB run)  //时间片轮转调度算法
1、输入系统时间片
2while(ready->next) do
3、    对当前就绪队列中的进程进行计数,为count
4for(i=1;i<=count;i++) do
5、        拿下就绪队列的第一个节点,修改状态为运行态
6、        将节点插入到运行队列中;
7if((该运行进程的需要时间-时间片)>0) then
8、            将该与运行进程的剩余时间-时间片后,从运行队列取出
9、            将其插入就绪队列末尾
10else
11、            直接将该运行进程从运行队列删去
12、        end if
13、    end for
14、    遍历就绪队列,打印出所有进程的信息:进程名和剩余时间
15、    按任意键继续;
16、end while

算法8void ftime(PCB ready,PCB run)  //高优先权优先调度算法
输入:ready、run队列
输出:无
1、删除run队列中正在运行的进程
2、q<-ready->next;
3、time<-ready->next->runtime;   //将就绪队列首个进程的运行时间赋给time
4while(q) do
5if(q节点的运行时间小于time) then
6、        time<-q节点运行时间
7、        让r指针指向q节点
8、        q<-q->next
9else 
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:
短进程优先调度算法和高优先权优先调度算法的代码基本一致,高优先权优先调度算法是每一次选择就绪队列中优先权最高的,短进程优先调度算法则是每一次选择就绪队列中运行时间最短的。所以写完了高优先权优先调度算法的代码,可以直接将找最高优先权部分变为找最短运行时间,这样短进程优先调度算法的代码可以很快得到。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
进程调度算法模拟。通过对进程调度算法模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。 (1) 用C、C++、Java语言编程实现对5个进程采用动态优先权调度算法进行调度的过程。数据如下: 5个进程的到达时刻和服务时间见下表,忽略I/O以及其它开销时间,使用动态优先权算法进行调度,优先权初始值为100,请输出各个进程的完成时刻、周转时间、带权周转时间。 进程 到达时刻 服务时间 A 0 3 B 2 6 C 4 4 D 6 5 E 8 2 (2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段(用不到的字段可以不定义)。  进程标识数ID。  进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。  进程已占用CPU时间CPUTIME。  进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。  进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。  进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。  进程状态STATE。  队列指针NEXT,用来将PCB排成队列。 (3)优先数改变的原则:  进程在就绪队列中呆一个时间片,优先数增加1。  进程每运行一个时间片,优先数减3。 (4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。 (5)分析程序运行的结果,谈一下自己的认识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

用户283772836617353849

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值