操作系统B实验报告 2.docx
《操作系统B实验报告 2.docx》由会员分享,可在线阅读,更多相关《操作系统B实验报告 2.docx(21页珍藏版)》请在冰豆网上搜索。
操作系统B实验报告2
本科实验报告
课程名称:
操作系统B
实验项目:
进程调度实验设计
实验地点:
逸夫楼504
专业班级:
软件1006班学号:
2010004502
学生姓名:
白双元
指导教师:
方昀
2012年11月28日
实验题目
进程调度试验设计
实验目的和要求
(一)目的
进程是操作系统最重要的概念之一,进程调度是操作系统的主要内容,本实验要求学生独立地用高级语言编写一个进程调度程序,调度算法可任意选择或自行设计,本实验可使学生加深对进程调度和各种调度算法的理解。
(二)要求
1.设计一个有几个进程并发执行的进程调度程序,每个进程由一个进程控制块(PCB)表示,进程控制块通常应包括下述信息:
进程名,进程优先数,进程需要运行的时间,占用CPU的时间以及进程的状态等,且可按照调度算法的不同而增删。
2.调度程序应包含2—3种不同的调度算法,运行时可以任选一种,以利于各种方法的分析和比较。
3.系统应能显示或打印各进程状态和参数的变化情况,便于观察。
实验内容及原理
1.题目本程序可选用优先数法或简单轮转法对五个进程进行调度。
每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假定起始状态都是就绪状态W。
为了便于处理,程序中进程的运行时间以时间片为单位计算。
各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。
进程控制块结构如表2-1所示:
表2-1PCB
进程标识符
链指针
优先数/轮转时间片数
占用CPU时间片数
进程所需时间片数
进程状态
进程控制块链结构如图2-1所示:
RUNHEADTAIL
…
图2-1进程控制块链结构
其中:
RUN—当前运行进程指针;
HEAD—进程就绪链链首指针;
TAIL—进程就绪链链尾指针。
2.算法与框图程序框图如图2-2所示。
图2-2进程调度框图
(1)优先数法。
进程就绪链按优先数大小从大到小排列,链首进程首先投入运行。
每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3。
理由是该进程如果在一个时间片中完成不了,优先级应降低一级。
接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续运行,否则,调度就绪链链首进程投入运行。
原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。
(2)简单轮转法。
进程就绪链按各进程进入的先后次序排列,链首进程首先投入运行。
进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相应于优先数法的优先数记录项位置)。
每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。
主要仪器设备
硬件:
笔记本电脑软件:
VisualStudio2010
操作方法与实验步骤
源代码:
#include
#include
#definefurthest5
structprocess/*PCBSTRUCTURE*/
{
intid;
intpriority;
intcputime;
intalltime;
charstate;
intnext;
}prochain[furthest-1];
intprocnum;
intrand();
intalgo;
intrun,head,tail,j;
voidprint();
voidinsert(intq);
voidinit();
voidprisch();
voidtimesch();
main()/*MAINPROGRAM*/
{
agan:
printf("typethealgorithmis(1:
RR,2:
PRIO):
");
scanf("%d",&algo);
if(algo==2)
{
printf("outputofpriority.\n");
init();
prisch();
}
else
{
if(algo==1)
{
printf("outputofroundrobin.\n");
init();
timesch();
}
else
{
printf("tryagain,please\n");
gotoagan;
}
}
for(j=1;j<=40;j++)
{
printf("=");
}
printf("\n\n");
for(j=1;j<=40;j++)
{
printf("=");
}
printf("\n\n");
printf("systemfinished\n");
}
voidprint()/*PRINTTHERUNNINGPROCESS,WAITING
QUEUEANDPCBSEQUENCELIST*/
{
intk,p;
for(k=1;k<=40;k++)
printf("=");
printf("\nrunningproc.");
printf("waitingqueue.");
printf("\n%d",prochain[run].id);
p=head;
while(p!
=0)
{
printf("%5d",p);
p=prochain[p].next;
}
printf("\n");
for(k=1;k<=40;k++)
printf("=");
printf("\n");
printf("id");
for(k=1;kprintf("%5d",prochain[k].id);
printf("\n");
printf("priority");
for(k=1;kprintf("%5d",prochain[k].priority);
printf("\n");
printf("cputime");
for(k=1;kprintf("%5d",prochain[k].cputime);
printf("\n");
printf("alltime");
for(k=1;kprintf("%5d",prochain[k].alltime);
printf("\n");
printf("state");
for(k=1;kprintf("%5c",prochain[k].state);
printf("\n");
printf("next");
for(k=1;kprintf("%5d",prochain[k].next);
printf("\n");
}
voidinsert(intq)/*INSERTAPROCESS*/
{
intp,s;
p=head;
s=prochain[head].next;
while((prochain[q].priority=0))
{
p=s;
s=prochain[s].next;
}
prochain[p].next=q;
prochain[q].next=s;
}
voidinsert2()/*PUTAPROCESSONTOTHETAILOFTHEQUEUE*/
{
prochain[tail].next=run;
tail=run;
prochain[run].next=0;
}
voidinit()/*CREATEAWAITINGQUEUE*/
{
inti;
head=0;
if(algo==2)
{
for(i=1;i{
prochain[i].id=i;
prochain[i].priority=(rand()+11)%41+1;
prochain[i].cputime=0;
prochain[i].alltime=(rand()+1)%7+1;
prochain[i].state='W';
prochain[i].next=0;
if((prochain[i].priority=0))
insert(prochain[i].id);
else
{
prochain[i].next=head;
head=prochain[i].id;
}
}
}
else
{
for(i=1;i{
prochain[i].id=i;
prochain[i].priority=(rand()+1)%3+1;
prochain[i].cputime=0;
prochain[i].alltime=(rand()+1)%7+1;
prochain[i].state='W';
prochain[i].next=(i+1)%(furthest+1);
}
head=1;
tail=furthest;
prochain[furthest].next=0;
}
run=head;
prochain[run].state='R';
head=prochain[head].next;
prochain[run].next=0;
print();
}
voidprisch()/*THEPROCESSWITHPRIOALGORITHM*/
{
while(run!
=0)
{
prochain[run].cputime+=1;
prochain[run].priority-=3;
prochain[run].alltime-=1;
if(prochain[run].alltime==0)
{
prochain[run].state='F';
prochain[run].next=0;
if(head!
=0)
{
run=head;
prochain[run].state='R';
head=prochain[head].next;
}
else
{
prochain[0].id=prochain[run].id;
run=0;
}
}
else
{
if((prochain[run].priority=0))
{
prochain[run].state='W';
insert(run);
run=head;
prochain[run].state='R';
head=prochain[head].next;
}
}
print();
}
}
voidtimesch()/*THEPROCESSWITHRRALRORITHM*/
{
while(run!
=0)
{
prochain[run].alltime-=1;
prochain[run].cputime+=1;
if(prochain[run].alltime==0)
{
prochain[run].state='F';
prochain[run].next=0;
if(head!
=0)
{
run=head;
prochain[run].state='R';
head=prochain[head].next;
}
else
{
prochain[0].id=prochain[run].id;
run=0;
}
}
else
{
if((prochain[run].cputime==prochain[run].priority)&&(head!
=0))//判断CPU的时间片是否到了
{
prochain[run].state='W';
prochain[run].cputime=0;
insert2();
run=head;
prochain[run].state='R';
head=prochain[head].next;
}
}
print();
}
}
实验结果与分析
1)时间片轮转法:
进程1完成的前后状态
2)按优先级调度:
进程3完成的前后状态
结果分析
截图很长,挺麻烦的,代码看的并不是很懂,但总体来说,是有收获的。
按时间片轮转算法将CPU的时间划分成很小的时间片分配给在CPU上运行的进程,进程在CPU的就绪队列中按照到来的先后顺序排队,CPU按排队的顺序依次调度进程,当时间片用完时,退出CPU,排到就绪队列的队尾。
这样的调度算法使得CPU中的进程得到CPU控制权的机会相等,但是对于紧急的进程得不到及时的处理。
按优先级调度算法在创建进程时,按照进程需要CPU的紧迫程度,为每一个进程分配优先级,在CPU的就绪队列中,进程按照优先级的顺序排队,随着进程的执行,每执行一次进程的优先级减少相应的数字,这样紧迫的进程和任务能够得到优先解决,但是对于优先级低占用CPU时间少的进程不能够得到及时的处理。