操作系统课程设计报告.docx
- 文档编号:24964387
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:21
- 大小:612.81KB
操作系统课程设计报告.docx
《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(21页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告
操作系统课程设计
学院:
信息科学与工程学院
专业:
计算机科学与技术
班级:
计xxxx
学号:
20131222xxx
学生姓名:
xxx
指导教师:
xxx
2015年7月23日
一、实验内容
设计一个有N个进程的进程调度程序
[问题描述]
通过一个简单的进程调度模拟程序的实现,加深对各种进程调度算法,进程切换的理解。
[基本要求]
1、进程调度算法:
采用动态最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)。
2、每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名---进程标示数ID
优先数PRIORITY优先数越大优先权越高
到达时间---进程的到达时间为进程输入的时间。
、
进程还需要运行时间ALLTIME,进程运行完毕ALLTIME=0,
已用CPU时间----CPUTIME、
进程的阻塞时间STARTBLOCK-表示当进程在运行STARTBLOCK个时间片后,进程将进入阻塞状态
进程的阻塞时间BLOCKTIME--表示当进程阻塞BLOCKTIME个时间片后,进程将进入就绪状态
进程状态—STATE
队列指针NEXT用来将PCB排成队列。
3、调度原则:
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
进程在就绪队列中待一个时间片,优先数加1
每个进程的状态可以是就绪R(READY)、运行R(Run)阻塞B(BLOCK)、或完成F(Finish)四种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减3,然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
二、数据结构设计
//定义PCB块结构体
structpcb{
intID;//进程ID
intPRIORITY;//优先数
intREACH;//到达时间
intCPUTIME;//CPU时间
intALLTIME;//运行时间
intSTARTBLOCK;//开始阻塞时间
intBLOCKTIME;//阻塞时间
intSTATE;//进程状态
structpcb*NEXT;//队列指针
};
//函数定义
voiddisplay(pcb*p);//结构体数据输出函数
voidinput();//进程信息初始化函数
voidwait();//就绪队列优先级操作
voidblock();//阻塞队列阻塞时间操作
voidrunning();//进程运行操作
voidinsertwait(pcb*insert);//将PCB块插入到就绪队列
voidinsertreach(pcb*insert);//将PCB块插入到未到达队列
voidinsertblock(pcb*insert);//将PCB块插入到阻塞队列
voidinsertfinish(pcb*insert);//将PCB块插入到完成队列
voidresort(pcb*head,pcb*insert);//对就绪队列进程重新排序
voidchange();//将就绪队列首位状态修改为运行
//定义全局变量
//定义全局结构体指针变量—就绪队列,未到达队列,阻塞队列,完成队列
structpcb*waiting=NULL,*reaching=NULL,*blocking=NULL,*finished=NULL;
inttotal=0;//定义全局变量—总CPU时间
三、算法设计(总体设计及模块设计)
四、测试数据及程序运行情况
测试数据:
运行情况:
五、实验过程中出现的问题及解决方法
①由于长时间未使用C语言编程,对链表的使用变得很陌生,所以花了一天的时间学习链表的相关知识。
②如何使未到达队列或阻塞队列的进程进入就绪队列也花了很长时间,后来想到对未到达队列的进程按照到达时间从小到大的顺序排列,对阻塞队列的进程按照阻塞时间的顺序进行排序,然后每次将到达时间减1,到达时间为零的时候、将阻塞时间减1,阻塞时间为零的时候插入到就绪队列,并从未到达队列、阻塞队列删除。
③由于链表的使用依然不太熟练,所以如果当未到达队列有几个进程的到达时间相同,却每次只能将一个进程成功移动到就绪队列。
现在依然没想到方法解决。
六、参考文献
七:
附录:
源代码
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"stdlib.h"
#include
#definegetpch(type)(type*)malloc(sizeof(type))
//PCB结构体
structpcb{
intID;
intPRIORITY;//优先数
intREACH;//到达时间
intCPUTIME;//CPU时间
intALLTIME;//运行时间
intSTARTBLOCK;//阻塞时间
intBLOCKTIME;//被阻塞时间
intSTATE;//进程状态
structpcb*NEXT;//队列指针
};
//函数初始化
voidblock();
voiddisplay(pcb*p);
voidinput();
voidwait();
voidrunning();
voidinsertwait(pcb*insert);
voidinsertreach(pcb*insert);
voidinsertblock(pcb*insert);
voidinsertfinish(pcb*insert);
voidresort(pcb*head,pcb*insert);
voidchange();
//定义全局变量
structpcb*waiting=NULL,*reaching=NULL,*blocking=NULL,*finished=NULL;
inttotal=0;
//就绪队列排序函数
voidresort(pcb*head,pcb*insert){
pcb*p0,*p1,*p2;
p0=insert;
p1=head;
if(head==NULL){
head=insert;
}else{
//根据到达时间将数据插入未到达队列
//遍历节点,与新节点比较大小
while((p0->PRIORITY
=NULL)){
p2=p1;
p1=p1->NEXT;
}
if(p0->PRIORITY>=p1->PRIORITY){
//判断该节点是否为头节点,如果是,则将新节点设置为头节点
if(p1==head){
head=p0;
}else{
p2->NEXT=p0;
}
p0->NEXT=p1;
}else{
p1->NEXT=p0;
p0->NEXT=NULL;
}
}
waiting=head;
}
//插入到就绪队列
voidinsertwait(pcb*insert){
insert->STATE=1;
pcb*p0,*p1,*p2;
p0=insert;
p1=waiting;
if(waiting==NULL){
waiting=insert;
}else{
//根据到达时间将数据插入未到达队列
//遍历节点,与新节点比较大小
while((p0->PRIORITY
=NULL)){
p2=p1;
p1=p1->NEXT;
}
if(p0->PRIORITY>=p1->PRIORITY){
//判断该节点是否为头节点,如果是,则将新节点设置为头节点
if(p1==waiting){
waiting=p0;
}else{
p2->NEXT=p0;
}
p0->NEXT=p1;
}else{
p1->NEXT=p0;
p0->NEXT=NULL;
}
}
}
//插入到未到达队列
voidinsertreach(pcb*insert){
insert->STATE=0;
pcb*p0,*p1,*p2;
p0=insert;
p1=reaching;
if(reaching==NULL){
reaching=insert;
}else{
//根据到达时间将数据插入未到达队列
//遍历节点,与新节点比较大小
while((p0->REACH>p1->REACH)&&(p1->NEXT!
=NULL)){
p2=p1;
p1=p1->NEXT;
}
if(p0->REACH<=p1->REACH){
//判断该节点是否为头节点,如果是,则将新节点设置为头节点
if(p1==reaching){
reaching=p0;
}else{
p2->NEXT=p0;
}
p0->NEXT=p1;
}else{
p1->NEXT=p0;
p0->NEXT=NULL;
}
}
}
//插入到阻塞队列
voidinsertblock(pcb*insert){
insert->STATE=3;
pcb*p0,*p1,*p2;
p0=insert;
p1=blocking;
if(blocking==NULL){
blocking=insert;
}else{
//根据阻塞时间将数据插入阻塞队列
//遍历节点,与新节点比较大小
while((p0->BLOCKTIME>p1->BLOCKTIME)&&(p1->NEXT!
=NULL)){
p2=p1;
p1=p1->NEXT;
}
if(p0->BLOCKTIME<=p1->BLOCKTIME){
//判断该节点是否为头节点,如果是,则将新节点设置为头节点
if(p1==blocking){
blocking=p0;
}else{
p2->NEXT=p0;
}
p0->NEXT=p1;
}else{
p1->NEXT=p0;
p0->NEXT=NULL;
}
}
}
//插入到已完成队列
voidinsertfinish(pcb*insert){
insert->STATE=4;
pcb*p0,*p1,*p2;
p0=insert;
p1=finished;
if(finished==NULL){
finished=insert;
}else{
//根据到达时间将数据插入未到达队列
//遍历节点,与新节点比较大小
while((p0->ALLTIME
=NULL)){
p2=p1;
p1=p1->NEXT;
}
if(p0->ALLTIME>=p1->ALLTIME){
//判断该节点是否为头节点,如果是,则将新节点设置为头节点
if(p1==finished){
finished=p0;
}else{
p2->NEXT=p0;
}
p0->NEXT=p1;
}else{
p1->NEXT=p0;
p0->NEXT=NULL;
}
}
}
//进程运行函数
voidrunning(){
pcb*p,*p1;
waiting->CPUTIME++;
//当CPUTIME等与ALLTIME时进城完成,插入到完成队列
if(waiting->CPUTIME==waiting->ALLTIME){
printf("\n\n\n进程[%d]已完成\n\n\n",waiting->ID);
p1=waiting;
waiting=waiting->NEXT;
p1->NEXT=NULL;
insertfinish(p1);
}else{
waiting->PRIORITY-=3;
//当CPUTIME等与STARTBLOCK,进程开始阻塞,插入到阻塞队列
if(waiting->CPUTIME==waiting->STARTBLOCK){
p=waiting;
waiting=waiting->NEXT;
p->NEXT=NULL;
//使STARTBLOCK=-1,防止再次进入阻塞队列
p->STARTBLOCK=-1;
insertblock(p);
}
}
}
//就绪队列优先数加1
voidwait(){
pcb*p0;
if(waiting->NEXT!
=NULL){
p0=waiting->NEXT;
}
while(p0!
=NULL){
p0->PRIORITY++;
p0=p0->NEXT;
}
}
//未到达队列到达时间减1
voidreach(){
pcb*p1,*temp,*p2;
p1=reaching;
while(p1!
=NULL){
p1->REACH--;
if(p1->REACH==0){
if(p1->NEXT==NULL){
insertwait(p1);
reaching=NULL;
}else{
p2=reaching;
reaching=reaching->NEXT;
p2->NEXT=NULL;
insertwait(p2);
}
}
p1=p1->NEXT;
}
}
//阻塞队列阻塞时间减1
voidblock(){
pcb*p2,*temp;
//阻塞队列阻塞时间减1
p2=blocking;
while(p2!
=NULL){
p2->BLOCKTIME--;
if(p2->BLOCKTIME==0){
p2->BLOCKTIME=-1;
if(p2->NEXT==NULL){
insertwait(p2);
blocking=NULL;
}else{
temp=p2->NEXT;
p2->NEXT=NULL;
blocking=temp;
insertwait(p2);
}
}
p2=p2->NEXT;
}
}
//输入数据函数
voidinput(){
pcb*temp=getpch(pcb);
//初始化进程
//生成随机数
srand((unsigned)time(NULL));
printf("请输入进程ID:
");
scanf("%d",&temp->ID);
//temp->ID=rand()%20+1;
temp->PRIORITY=rand()%10+1;
temp->REACH=rand()%3;
temp->ALLTIME=rand()%5+4;
temp->STARTBLOCK=rand()%2+2;
temp->BLOCKTIME=rand()%5+2;//被阻塞时间
temp->CPUTIME=0;//CPU时间
temp->NEXT=NULL;//队列指针
if(temp->REACH==0){
insertwait(temp);
}else{
insertreach(temp);
}
}
//显示函数
voiddisplay(pcb*p){
//从队列头指针开始输出
pcb*pr=p;
printf("ID\t优先数\t总时间\t运行时间\t到达进入阻塞阻塞时间状态\n");
while(pr!
=NULL){
printf("%d\t%d\t%d\t%d\t\t%d\t%d\t%d\t%d\n",pr->ID,pr->PRIORITY,pr->ALLTIME,pr->CPUTIME,pr->REACH,pr->STARTBLOCK,pr->BLOCKTIME,pr->STATE);
pr=pr->NEXT;
}
}
//将阻塞队列首位进程设置为运行状态
voidchange(){
if(waiting!
=NULL){
waiting->STATE=2;
pcb*pr=waiting->NEXT;
while(pr!
=NULL){
pr->STATE=1;
pr=pr->NEXT;
}
}
}
intmain(){
intc;
printf("请输入进程数:
");
scanf("%d",&c);
//输入进程号,初始化进程
for(inti=0;i input(); } //输入完成之后预览 printf("*******************就绪队列*******************\n"); display(waiting); printf("\n\n*******************未到达队列*******************\n"); display(reaching); printf("\n\n*******************阻塞队列*******************\n"); display(blocking); system("pause"); printf("进程开始运行\n"); //当就绪,未到达,阻塞三个队列都不为空时执行 while(waiting! =NULL||reaching! =NULL||blocking! =NULL){ total++; if(waiting! =NULL){ running(); } if(waiting! =NULL&&waiting->NEXT! =NULL){ wait(); } if(reaching! =NULL){ reach(); } if(blocking! =NULL){ block(); } if(waiting! =NULL&&waiting->NEXT! =NULL){ resort(waiting->NEXT,waiting); } printf("\n\n\n当前CPU执行时间为%d\n\n\n",total); printf("*******************就绪队列*******************\n"); change(); display(waiting); printf("\n\n*******************未到达队列*******************\n"); display(reaching); printf("\n\n*******************阻塞队列*******************\n"); display(blocking); system("pause"); } //显示最终运行结果 printf("所有进程已完成,下面为运行结果\n"); printf("共运行了%d个时间片\n\n",total); printf("\n\n*******************已完成进程列表*******************\n\n"); display(finished); system("pause"); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 报告