进程调度.docx
《进程调度.docx》由会员分享,可在线阅读,更多相关《进程调度.docx(19页珍藏版)》请在冰豆网上搜索。
进程调度
淮海工学院计算机工程学院
实验报告书
课程名:
《操作系统原理》
题目:
实验一:
进程调度
学号:
姓名:
一、实验目的
1.设计一个模拟进程调度的算法
2.理解进程控制块的结构
3.理解进程运行的并发性
4.掌握进程调度的几种基本算法
二、实验要求
1.在多道程序运行环境下,进程数目一般多于处理机数目,使得进程要通过竞争来使用处理机——分配处理机的任务由进程调度程序完成。
2.系统为了便于对进程进行管理,将系统中的所有进程按其状态组织成不同的进程队列,如运行队列、就绪队列和等待队列。
3.进程调度的功能就是从就绪队列中挑选一个进程到处理机上运行。
常用的有优先级调度算法、先来先服务算法、时间片轮转算法等。
三、实验步骤
操作系统WindowsXP,开发工具VC++6.0
1.打开VC,选择菜单项File->New,选择Project选项卡并建立一个名为processes的win32consoleapplication工程;
2.在工程中创建源文件processes.cpp:
选择菜单项Project->AddtoProject->File,此时将打开一个新窗口,在其中输入想要创建的文件名,这里是processes.cpp,在其中编辑好并保存。
3.通过调用菜单项Build->Rebuildall进行编译连接,可以在指定的工程目录下得到processes.exe程序,运行即可。
4.要求完成先来先服务算法、时间片轮转算法和短作业优先算法完成进程调度。
四、实验结果分析
1.建立工程
2.选择工程格式
3.向工程中添加文件
4.先来先服务算法演示
5.短作业优先算法演示
6.时间片轮转算法演示
7.优先数算法演示
五、实验小结
这次的实验主要是对各种算法的实现,指针用起来比较绕人,一直是我比较薄弱的地方,所以这次实验用的时间比较的长,但完成这次实验之后,我对指针更加了解了,相信在以后的应用中应该能够得心应手。
短作业优先是花时间最多的,因为它要考滤的因素比较多,不仅要比较到达时间和服务时间,还有到达时间和CUP现在的时间位置的比较,所以嵌套比较多。
附:
1、短作业优先和先来先服务:
#include"stdio.h"
#include"stdlib.h"
typedefstructPCB//定义进程控制块
{
charID[3];//进程号
charname[10];//进程名
charstate;//运行状态
intarrivetime;//到达时间
intstarttime;//进程开始时间
intfinishtime;//进程结束时间
intservicetime;//服务时间
floatturnaroundtime;//周转时间
floatweightedturnaroundtime;//带权周转时间
structPCB*next;//指向下个进程
}pcb;
inttime=0;//计时器
intn;//进程个数
pcb*head=NULL,*p,*q,*Y;//进程链表指针
voidrun_fcfs(pcb*p1)//运行未完成的进程
{
p1->starttime=time;
printf("\n现在时间是%d,开始运行作业%s\n",time,p1->name);
time+=p1->servicetime;
p1->state='T';
p1->finishtime=time;
p1->turnaroundtime=p1->finishtime-p1->arrivetime;
p1->weightedturnaroundtime=p1->turnaroundtime/p1->servicetime;
printf("ID到达时间开始时间服务时间完成时间周转时间带权周转时间\n");
printf("%s%6d%10d%10d%8d%10.1f%10.2f\n",
p1->ID,p1->arrivetime,p1->starttime,p1->servicetime,p1->finishtime,
p1->turnaroundtime,p1->weightedturnaroundtime);
}
voidsfc()//找到当前未完成的进程
{printf("\n**您选择了短作业优先算法:
**");
inti,j,k,x=1;
p=head;time=0;
for(i=0;i{
for(j=0;j{
if(p->state=='F')
{
if(p->arrivetime<=time)
{
q=head;x=p->servicetime;
for(k=0;k{
if(q->state=='F')
{
if(q->arrivetime<=time)
{
if(x>q->servicetime)
{
x=q->servicetime;
Y=q;
}
}
else
{
Y=q;break;
}
}
q=q->next;
}
}
else
{
Y=p;break;
}
}
p=p->next;
}
if(x)
{
p=Y;//标记当前未完成的进程
run_fcfs(p);
}
p=head;x=0;Y=NULL;
}
for(i=0;i{
if(p->state=='F')
{
run_fcfs(p);
}
p=p->next;
}
}
voidfcfs()
{
printf("\n**您选择了先来先服务算法:
**");
inti,j;
p=head;
for(i=0;i{
if(p->state=='F')
{
q=p;//标记当前未完成的进程
run_fcfs(q);
}
p=p->next;
}
}
voidgetInfo()//获得进程信息并创建进程
{
intnum;
printf("\n作业个数:
");
scanf("%d",&n);
printf("依次输入:
\nID进程名到达时间服务时间\n");
for(num=0;num{
p=(pcb*)malloc(sizeof(pcb));
scanf("%s%s%d%d",&p->ID,&p->name,&p->arrivetime,&p->servicetime);
if(head==NULL){head=p;q=p;time=p->arrivetime;}
if(p->arrivetime
q->next=p;
p->starttime=0;
p->finishtime=0;
p->turnaroundtime=0;
p->weightedturnaroundtime=0;
p->next=NULL;
p->state='F';
q=p;
}
}
voidmain()
{charz;
printf("请输入选择算法F、S(先来先服务、短作业优先):
");
scanf("%c",&z);
getInfo();
p=head;
if(z=='F')
fcfs();
elseif(z=='S')
sfc();
else
printf("输入有误,请重新输入");
}
2:
优先数和时间轮转算法:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedefstructnode
{charname[10];/*进程标识符*/
intprio;/*进程优先数*/
intround;/*进程时间轮转时间片*/
intcputime;/*进程占用CPU时间*/
intneedtime;/*进程到完成还需要的时间*/
intcount;/*计数器*/
charstate;/*进程的状态*/
structnode*next;/*链指针*/
}PCB;
PCB*finish,*ready,*tail,*run;/*队列指针*/
intN,t;/*进程数*/
/*将就绪队列中的第一个进程投入运行*/
voidfirstin()
{run=ready;/*就绪队列头指针赋值给运行头指针*/
run->state='R';/*进程状态变为运行态*/
ready=ready->next;/*就绪队列头指针后移到下一个进程*/
}
/*标题输出函数*/
voidprt1(chara)
{/*优先数法*/
if(toupper(a)=='P')
printf("进程号cpu时间所需时间优先数状态\n");
/*轮转法*/
elseif(toupper(a)=='R')
printf("进程名占用CPU时间到完成还要的时间轮转时间片状态\n");
}
/*进程PCB输出*/
voidprt2(chara,PCB*q)
{if(toupper(a)=='P')/*优先数法的输出*/
printf("%-8s%-8d%-8d%-8d%c\n",
q->name,q->cputime,q->needtime,q->prio,q->state);
elseif(toupper(a)=='R')/*轮转法的输出*/
printf("%4s%8d%12d%14d%8c\n",q->name,q->cputime,q->needtime,q->round,q->state);
}
/*输出函数*/
voidprt(charalgo)
{PCB*p;
prt1(algo);/*输出标题*/
if(run!
=NULL)prt2(algo,run);/*如果运行指针不空,输出当前PCB*/
p=ready;/*输出就绪队列PCB*/
while(p!
=NULL)
{prt2(algo,p);
p=p->next;
}
p=finish;/*输出完成队列PCB*/
while(p!
=NULL)
{prt2(algo,p);
p=p->next;
}
getchar();/*按任意键继续*/
}
/*优先数的插入算法*/
insert1(PCB*q)
{PCB*p1,*s,*r;
intb;
s=q;/*待插入的PCB指针*/
p1=ready;/*就绪队列头指针*/
r=p1;/*r做p1的前驱指针*/
b=1;
while((p1!
=NULL)&&b)/*根据优先数确定插入位置*/
if(p1->prio>=s->prio)
{r=p1;
p1=p1->next;
}
elseb=0;
if(r!
=p1)/*如果条件成立则插入在r与p1之间*/
{r->next=s;
s->next=p1;
}
else/*否则插入在就绪队列的头*/
{s->next=p1;
ready=s;
}
}
/*优先数法创建初始PCB信息*/
voidcreate1(charalg)
{PCB*p;
inti,time;
charna[10];
ready=NULL;/*就绪队列头指针*/
finish=NULL;/*完成队列头指针*/
run=NULL;/*运行队列指针*/
printf("进程名需要运行的时间:
\n");/*输入进程信息创建PCB*/
for(i=1;i<=N;i++)
{p=(PCB*)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='w';
p->prio=50-time;
if(ready!
=NULL)
insert1(p);/*就绪队列不空则插入*/
else/*否则创建第一个PCB*/
{p->next=ready;
ready=p;
}
}
printf("优先数算法输出信息:
\n");
printf("**************************************\n");
prt(alg);/*输出进程PCB信息*/
run=ready;/*将就绪队列的第一个进程投入运行*/
ready=ready->next;
run->state='R';
}
/*优先数调度算法*/
priority(charalg)
{
while(run!
=NULL)/*当运行队列不空时,有进程正在运行*/
{
run->cputime++;run->needtime--;
run->prio-=3;/*每运行一次优先数降低3个单位*/
if(run->needtime==0)/*如所需时间为0将其插入完成队列*/
{run->next=finish;finish=run;
run->state='F';/*置状态为完成态*/
run=NULL;/*运行队列头指针为空*/
if(ready!
=NULL)firstin();
/*如就绪队列不空,将其第一个进程投入运行*/
}
elseif((ready!
=NULL)&&(run->prioprio))
/*没有运行完同时优先数不是最大,则将其变为就绪并插入队列*/
{run->state='W';insert1(run);
firstin();/*将就绪队列第一个进程投入运行*/
}
prt(alg);
}
}
voidcreate(charalg)//时间片轮转法创建链表进程PCB
{
PCB*p;
inti,time;
charna[10];
ready=NULL;
finish=NULL;
run=NULL;
printf("进程名需要运行的时间:
\n");
for(i=1;i<=N;i++)
{
p=newPCB;
scanf("%s%d",&na,&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='W';//进程的状态
p->round=0;
if(ready!
=NULL)
insert1(p);
else
{
p->next=ready;
ready=p;
}
}
printf("*************时间片轮转法进程调度过程*************\n");
prt(alg);
run=ready;
ready=ready->next;
run->state='R';
}
voidtimeslicecycle(charalg)//时间片轮转法
{
while(run!
=NULL)
{
run->cputime=run->cputime+t;//处理时间加t
run->needtime=run->needtime-t;//完成需要时间减t
run->round=run->round+t;//运行完将其变为完成态,插入完成队列
if(run->needtime<=0)//当进程完成时
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!
=NULL)//就绪队列不空,将第一个进程投入进行
firstin();
}
else
{
run->state='W';//将进程插入到就绪队列中等待轮转
insert1(run);//将就绪队列的第一个进程投入运行
firstin();
}
prt(alg);
}
}
main()
{charalgo;/*算法标记*/
printf("选择算法:
P/R(优先数算法/轮转法)\n");
scanf("%c",&algo);/*输入字符确定算法*/
printf("输入进程数:
\n");
scanf("%d",&N);/*输入进程数*/
if(algo=='P'&&N!
=0)
{create1(algo);/*优先数法*/
priority(algo);
}
elseif(algo=='R'&&N!
=0)
{
printf("定义时间片大小:
");
scanf("%d",&t);//输入时间片大小
create(algo);//创建进程
timeslicecycle(algo);//时间片轮转法调度
}
else
printf("输入无效或无进程");
}