操作系统实验报告.docx
- 文档编号:15640122
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:40
- 大小:263.71KB
操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(40页珍藏版)》请在冰点文库上搜索。
操作系统实验报告
操作系统实验报告
学院计算机学院
专业计算机科学与技术
班级2009级(7)班
学号3209006208
姓名陈玉仪
指导教师丁国芳
(2012年6月)
计算机学院计算机科学与技术专业09(7)班学号:
3209006208
姓名:
陈玉仪协作者:
________教师评定:
实验__一__题目进程调度
实验__二__题目作业调度__
实验平台:
计算机及操作系统:
PC机,Windowsxp;
数据库管理系统:
VisualC++6.0;
计算机学院计算机科学与技术专业09(7)班学号:
3209006208
姓名:
陈玉仪协作者:
________教师评定:
实验题目一、进程调度
1、实验目的
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
2、实验内容和要求
设计一个有N个进程并发的进程调度程序。
要求采用最高优先级数优先算法,时间片轮转算法,多级反馈队列调度算法这三种算法。
3、实验主要仪器设备和材料
硬件环境:
IBM-PC或兼容机
软件环境:
C++、C语言编译环境
四、实验原理及设计方案
1、实验原理
(1)最高优先数优先:
把CPU分配给就绪队列中优先数最高的进程。
(2)简单轮转:
所有就绪队列进程按FCFS拍成一个队列,总是把处理及分配给队首的进程,各进程占用CPU的时间片相同。
如果运行进程用完它的时间片后还未完成,就把它送回就绪队列的末尾,把处理机重新分配给队首的进程。
直至所有进程运行完毕。
2、设计方案
使用队列作为基本数据结构,使用结构体作为队列元素,每个元素表示一个PCB(ProcedureControlBlock)。
3、最高优先数优先:
遍历就绪队列,查找最高优先数最高者,抽取运行。
4、简单轮转:
每次运行队首元素,若在时间片内完成则销毁元素,否则插到队尾。
5、多级反馈:
创建多个队列,并赋予不同优先级别。
每次运行优先级最高队列队首元素,直至该队列为空再运行次级队列,以此类推。
添加的新进程插入到当前工作队列的前一优先级队列,下次运行仍从非空最高优先级队列开始运行。
3、相关数据结构的说明
/*定义进程块*/
typedefstructpcb{
charname;/*进程名称*/
charstate;/*进程状态*/
intntime;/*进程所需占用时间*/
intrtime;/*进程一占用时间*/
structpcb*next;/*节点指针*/
}PCB;
/*定义进程队列*/
typedefstruct{
PCB*head;/*队列头指针*/
PCB*tail;/*队列尾指针*/
}Queue;
4、程序流程图
(1)简单轮转算法
开始
初始化PCB,随机生成数据
是
就绪队列为空?
否
结束
就绪队列首进程投入运行
时间片到,进程已占用CPU时间+1
进程已占用CPU时间达到所需运行时间?
是
进程完成,撤销改进程
否
把进程插入就绪队列尾部
(2)多级反馈队列算法
开始
初始化PCB,随机生成数据
初始化就绪队列,设置多级队列优先级及时间片大小
当前优先级就绪队列为空?
是
否
是
次级就绪队列都为空?
就绪队列首进程投入运行
否
时间片到,进程已占用CPU时间+1
选择次优先级队列
进程已占用CPU时间达到所需运行时间?
是
进程完成,撤销改进程
否
把进程插入次级就绪队列尾部
结束
多级队列程序清单:
#include
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
#defineNULL0
structpcb{/*定义进程控制块PCB*/
charname[10];
charstate;
intsuper;
intntime;
intrtime;
intqueueNo;/*队列号*/
intetime;/*结束时间*/
floatquantime;/*带权周转时间*/
structpcb*link;
}*ready=NULL,*ready2=NULL,*ready3=NULL,*endqueue=NULL,*p;
typedefstructpcbPCB;
intendtime;
voidinsert(structpcb**queue)/*插入函数,向传来的指针所指队列插入进程*/
{
PCB*nextq;/*指针q用于指向就绪队列队尾的进程,指针nextp用于判断是否指针是否到达队尾*/
if(*queue==NULL)
*queue=p;/*队列为空,插入就绪队列*/
else
{
nextq=*queue;
while(nextq->link!
=NULL)/*查找队尾*/
{
nextq=nextq->link;
}
nextq->link=p;/*把进程p插入队尾*/
}
p->link=NULL;
}
voidinput()/*建立进程控制块函数*/
{
inti,num;
system("cls");/*清屏*/
printf("\n请输入进程数:
");
scanf("%d",&num);
for(i=1;i<=num;i++)/*进程编号从1开始*/
{
printf("\n进程名No.%d:
\n",i);
p=getpch(PCB);
printf("\n请输入进程名:
");
scanf("%s",p->name);
printf("\n请输入进程运行时间:
");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;
p->state='w';
p->link=NULL;
insert(&ready);/*新插入的进程都放在就绪队列ready*/
p->queueNo=1;
p->etime=0;
p->quantime=0;
}
}
intspace()/*建立查询进程个数函数*/
{
intl=0;
PCB*pr=ready;
while(pr!
=NULL)
{
l++;
pr=pr->link;
}
return(l);/*返回队列长度*/
}
voiddisp(PCB*pr)/*建立进程显示函数,用于显示当前进程*/
{
printf("\n进程名\t状态\t需要时间\t已用时间\t结束时间\t带权周转时间\n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
printf("|%d\t\t",pr->ntime);
printf("|%d\t\t",pr->rtime);
printf("|%d\t\t",pr->etime);
printf("|%f\t",pr->quantime);
printf("\n");
}
voidcheck()/*建立进程查看函数*/
{
PCB*pr;
printf("\n****当前正在运行的进程是:
%s",p->name);/*显示当前运行进程*/
disp(p);
pr=ready;
printf("\n");
printf("\n****第1个就绪队列状态为:
\n");/*显示第1个就绪队列状态*/
while(pr!
=NULL)
{
disp(pr);/*显示就绪队列*/
pr=pr->link;
}
pr=ready2;
printf("\n****第2个就绪队列状态为:
\n");/*显示第2个就绪队列状态*/
while(pr!
=NULL)
{
disp(pr);/*显示就绪队列*/
pr=pr->link;
}
pr=ready3;
printf("\n****第3个就绪队列状态为:
\n");/*显示第3个就绪队列状态*/
while(pr!
=NULL)
{
disp(pr);/*显示就绪队列*/
pr=pr->link;
}
}
voidcheck2()/*建立运行完成后进程查看函数*/
{
PCB*pr;
pr=endqueue;
printf("\n****所有队列运行状况****\n");
while(pr!
=NULL)
{
disp(pr);/*显示就绪队列*/
pr=pr->link;
}
}
voiddestroy()/*建立进程撤销函数(进程运行结束,撤销进程)*/
{
printf("\n进程[%s]已完成.",p->name);
printf("\n完成时间:
[%d]",p->etime);
printf("\n带权周转时间:
[%f]",p->quantime);
p->state='F';
insert(&endqueue);
//free(p);
}
/*****/
voidrunning(intmtime)/*建立进程就绪函数(进程运行时间到,置就绪状态*/
{
inttime=p->queueNo*mtime;
if(p->ntime-p->rtime<=time)/*如果所需时间小于等于时间片时间*/
{
endtime=endtime+p->ntime-p->rtime;
p->rtime=p->ntime;
p->etime=endtime;
p->quantime=float(p->etime)/float(p->ntime);
destroy();/*调用destroy函数*/
}
else
{
p->rtime=p->rtime+time;
endtime=endtime+time;
p->state='w';
if(p->queueNo==1)
{
p->queueNo++;
insert(&ready2);
}
elseif(p->queueNo==2)
{
p->queueNo++;
insert(&ready3);
}
else
{
insert(&ready3);
}
}
}
voidmain()/*主函数*/
{
intlen,h=0;
charch;
input();
len=space();
intmtime;
printf("\n请输入时间片的大小:
");
scanf("%d",&mtime);
printf("\n");
while((len!
=0)&&(ready!
=NULL||ready2!
=NULL||ready3!
=NULL))
{
ch=getchar();
h++;
printf("\nTheexecutenumber:
%d\n",h);
if(ready!
=NULL)/*如果第1个队列不为空*/
{
p=ready;
ready=p->link;
}
elseif(ready2!
=NULL)
{
p=ready2;
ready2=p->link;
}
else
{
p=ready3;
ready3=p->link;
}
p->link=NULL;
p->state='R';
check();
running(mtime);
printf("\n当前运行时间为:
[%d]",endtime);
printf("\n按任一键继续.....");
ch=getchar();
}
printf("\n\n进程已经完成.\n");
check2();
ch=getchar();
free(p);
}
运行过程:
实验结果的分析及说明
简单轮转
多级反馈
优点
保证就绪队列中的所有进程在给定的时间内均能获得一时间片的处理机执行时间
能及时响应用户的请求,长短进程都能照顾到,合理的分配长短进程对处理机的占用。
缺点
时间片大小难以确定,时间片过小造成频繁发生中断、切换上下文,从而增加系统开销。
时间片过大,容易造成处理机空闲。
相对而言,算法复杂。
后加入的进程不一定晚完成。
结论:
多级反馈算法在进程调度方面的性能表现比简单轮转算法好,能很好满足各种类型的用户的需求。
五.思考题
哪种进程最适合于多级反馈队列调度,是偏重于处理机还是偏重于I/O型?
答:
处理机。
计算机学院计算机科学与技术专业09(7)班学号:
3209006208
姓名:
陈玉仪协作者:
________教师评定:
实验题目二、作业调度
1、实验目的
模拟作业调度的实现,用高级语言编写和雕饰一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。
2、实验内容和要求
1.为单道批处理系统设计一个作业调度程序
2.模拟批处理多道操作系统的作业调度
3、实验主要仪器设备和材料
硬件环境:
IBM-PC或兼容机
软件环境:
C++、C语言编译环境
四、实验原理及设计方案
1、实验原理
(1)先来先服务算法:
是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。
(2)短作业优先算法:
总是按作业要求运行的时间来选择作业,每次挑选要求运行时间短且资源要求能满足的作业先进入主存执行。
(3)高响应比优先调度算法:
根据作业要求服务时间和等待时间算出优先权,每次挑选优先权最高的作业先进入主存执行。
2、设计方案
(1)由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。
(2)在批处理系统中,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求,所需要的资源是否得到满足。
3、相关数据结构的说明
/*定义作业块*/
typedefstructjcb{
charname;/*作业名称*/
charstate;/*作业状态*/
intntime;/*所需时间*/
intrtime;/*提交时间*/
intresourse;/*所需资源*/
structjcb*next;/*节点指针*/
}JCB;
4、
程序流程图
(1)先到先服务算法
开始
开始
初始化JCB,随机生成数据
根据到达时间对JCB排序
获取队首指针p,用以遍历队列
p指向节点是否为空?
计算平均周转时间及带权平均周转时间
计算当前作业开始运行时刻、周转时间、完成时刻、带权周转时间
结束
累积周转时间和带权周转时间
移动指针p指向下一节点
(2)短作业优先算法
结束
(3)高响应比优先算法
结束
5、程序清单
#include
#include
#include
#include
#include
#include
#include
#defineNULL0
#defineTrue1
#defineFalse0
/*队列长度*/
#defineQueueLength12
/*随机数范围*/
#defineNum60
typedefintBool;
/*定义作业块*/
typedefstructjcb{
charname;
charstate;
intntime;/*所需时间*/
intrtime;/*提交时间*/
intresourse;
structjcb*next;
}JCB;
/*定义作业队列*/
typedefstruct{
JCB*head;
JCB*tail;
}Queue;
/*初始化队列*/
voidInit(Queue*q){
q->head=NULL;
q->tail=NULL;
}
/*生成n个进程组成的队列,返回作业队列*/
QueueCreat(intn){
Queueq;
JCB*s;
inti;
s=(JCB*)malloc(n*sizeof(JCB));
/*使用时间做种子产生随机数*/
srand((unsigned)time(NULL));
for(i=0;i s[i].name=(char)('A'+i); s[i].state='W'; s[i].ntime=rand()%(Num*2)+1; s[i].rtime=rand()%Num+1; s[i].resourse=rand()%Num+1; if(i! =n-1){ s[i].next=s+i+1; }else{ s[i].next=NULL; } } q.head=s; q.tail=s+n-1; returnq; } /*深度复制队列,返回副本*/ QueueCopy(Queueq1){ Queueq2; JCB*p,*temp; q2.head=NULL; q2.tail=NULL; p=q1.head; while(p! =NULL){ temp=(JCB*)malloc(sizeof(JCB)); temp->name=p->name; temp->ntime=p->ntime; temp->rtime=p->rtime; temp->resourse=p->resourse; temp->state=p->state; temp->next=NULL; if(q2.tail==NULL){ q2.head=temp; q2.tail=temp; }else{ q2.tail->next=temp; q2.tail=temp; } p=p->next; } returnq2; } /*节点值交换*/ voidswap(JCB*p1,JCB*p2){ JCBtemp,*next; if(p1==NULL||p2==NULL)return; /*内存复制实现交换*/ memcpy(&temp,p1,sizeof(JCB)); memcpy(p1,p2,sizeof(JCB)); memcpy(p2,&temp,sizeof(JCB)); /*交换节点*/ next=p1->next; p1->next=p2->next; p2->next=next; } /*按到达时间对队列进行排序*/ voidTimeSort(Queue*q){ JCB*p1,*p2,*small; if(q->head==NULL)return; p1=q->head; while(p1! =q->tail){ small=p1; p2=p1->next; while(p2! =NULL){ if(p2->rtime swap(p2,small); } p2=p2->next; } p1=p1->next; } } /*显示作业队列*/ voiddisplay(Queueq){ JCB*p; inti=0; if(q.head==NULL){ printf("队列为空。 \n"); }else{ p=q.head; printf("序号\t名称\t提交\t所需\t资源\t状态\n"); while(p! =NULL){ printf("%d\t%c\t%d\t%d\t%d\t%c\n",i++,p->name,p->rtime,p->ntime,p->resourse,p->state); p=p->next; } } } /*查看完成队列*/ voidcheck(Queueq){ JCB*p; /*lOver前一作业结束时间,nBegin当前作业开始时间*/ inti=0,lOver=0,nBegin,turnover,sum_turnover=0; floatweight,sum_weight=0; if(q.head==NULL){ printf("队列为空。 \n"); }else{ p=q.head; printf("序号\t名称\t提交\t所需\t开始\t完成\t周转\t带权\t资源\t响应比\n"); while(p! =NULL){ nBegin=lOver>p->rtime? lOver: p->rtime; turnover=nBegin+p->ntime-p->rtime; weight=(float)turnover/(float)p->ntime; lOver=nBegin+p->ntime; sum_turnover+=turnover; sum_weight+=weight; printf("%d\t%c\t%d\t%d\t%d\t%d\t%d\t%0.2f\t%d\t%0.2f\n", i++,p->name,p->rtime,p->ntime,nBegin,lOver,turnover,weight, p->resourse,(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告