OS实验报告.docx
《OS实验报告.docx》由会员分享,可在线阅读,更多相关《OS实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
![OS实验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/27/f31d0a57-942d-49ee-bee7-20ec688c92c7/f31d0a57-942d-49ee-bee7-20ec688c92c71.gif)
OS实验报告
操
作
系
统
实
验
报
告
学院:
计算机与软件
系:
计算机科学与技术
实验一进程调度设计
一、实验目的:
进程是操作系统的重要概念之一,进程调度是操作系统的主要内容此实验要求学生独立使用高级语言编写一个进程调度程序,调度算法可任意选择,本实验加深学生对进程调度及其算法的理解。
二、实验内容:
设计一个有几个进程并行的进程调度程序,每个进程有一个进程控制块pcb表示,进程控制块通常包括以下内容:
进程名,进程优先数,进程需要运行的时间。
站用cpu的时间一起运行状态等,并且可以按照调度算法的不同而增删。
三、实验要求:
1调度程序应包含2-3种的不同的调度算法,运行时可以任意选取一种,以利于各种方法的比较分析。
2系统应能显示或打印各进程的状态和参数变化情况,便于观察。
四、实验环境:
dev-c++;
五、实验步骤:
1本程序可选用优先数法或简单轮转法对5个进程进行调度,每个进程处于运行(R),就绪(W)和完成(F)三种状态之一,并假设起始状态为就绪状态(W)。
2为了便于处理,程序中进程的运行时间以时间片为单位计算,各进程的优先数或轮转时间片数以及进程需要运行的时间片数,均由伪随机数发生器产生。
3优先数法。
进程就绪按优先数大小从小到大排列,链首进程首先投入运行。
每过一个时间片运行进程所需要的时间片数减1,优先数也减3。
接着比较现行进程和就绪链首进程的优先数,若仍是现有进程的高或者相同。
则现有进程继续运行,否则调度就绪队列首进程投入运行,原进程按优先数大小插入就绪队列并且改变相应的进程状态。
直至所有进程运行完各自的时间片数。
4简单轮转法。
进程就绪链按各自进入的先后顺序排列,进程每次占用处理机的时间按其重要程度等等入进程控制快的轮转时间片书记录项,每过一个时间片。
运行进程占用处理机德时间片书加1,然后比较占用处理机德时间片数是否与该进程的轮转时间片书相等。
若相等说明已经达到轮转时间应将进程排到就绪链末尾,调度链首进程占用处理机,并且改变进程状态直至所有进程完成各自的时间片。
程序流程框图如下;
否
是
5源程序如下:
#include
#include
#definefurthest5
structprocess{
intid;
intpriority;
intcputime;
intalltime;
charstate;
intnext;
}prochain[furthest+1];
intprocnum;
intrand();
intalgo;
intrun,head,tail,j;
voidprint()
{
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");
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("stste");
for(k=1;kprintf("%5c",prochain[k].state);
printf("\n");
printf("next");
for(k=1;kprintf("%5d",prochain[k].next);
printf("\n");
}
insert(q)
{intp,s;
p=head;
s=prochain[head].next;
while((prochain[q].priority<
prochain[s].priority)&&(s!
=0))
s=prochain[s].next;
{p=s;
}
prochain[p].next=q;prochain[q].next=s;
}
voidinsert2()
{prochain[tail].next=run;
tail=run;prochain[run].next=0;
}
voidinit()
{inti;
if(algo==2)
{
for(i=1;i{
prochain[i].id=i;
prochain[i].priority=(rand()+1)%4+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;iprochain[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()
{
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()
{
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[run].next;
}
else{
prochain[0].id=prochain[run].id;
run=0;
}
}
else{
if((prochain[run].cputime==prochain[run].priority)&&(head!
=0))
{
prochain[run].state='W';
prochain[run].cputime=0;
insert2();
run=head;
prochain[run].state='R';
head=prochain[run].next;}
}print();
}
}
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");
getch();}
6运行过程及实验结果截图如下:
时间片轮转结果:
优先级算法结果:
六思考题
进程调度算法包括:
适于长作业的先来先服务算法,适于短作业的短作业优先调度算法。
优先权调度算法,响应系统及时的分时系统中的轮转调度算法。
实验二存储管理
一、实验目的:
存储管理的主要功能之一是合理的分配空间,请求页式管理是一种常用的虚拟存储管理技术。
此实验要求学生通过请求页式管理的页面置换算法的模拟设计来了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。
二、实验内容:
1页表中增加是否修改过的标志。
2设计地址转换程序来模拟硬件的地址转换和缺页中断。
3编制一个先进先出算法的调度程序4自行确定指令序列检查程序的正确性。
三、实验要求:
模拟页式虚拟存储管理中硬件的地址转换和缺页中断,并用先进先出算法(FIFO)处理缺页中断。
四、实验步骤:
1:
当装入一个页面必须置换列一个页面时,被选中的页面未被修改则不必重新写入磁盘,因此在页面中增加修改标志:
0表示未被修改,1表示执行过修改。
2地址转换程序:
当所访问的页在主存时形成绝对地址,可以使用输出转换后的绝对地址来表示一条指令的完成。
当所访问的页不再主存时则输入此页页号表示一次缺页中断。
3先进先出调度程序。
4试验流程控制如下;
5
6源代码如下:
#include
usingnamespacestd;
intpagenum=0;///内存的页面数
inttotal=0;///要访问的叶面总数
intlacknumber=0;///缺页的总数
intmain()
{
intarray[1][20];
inty=0,x=0;//0代表没有内容
for(y=0;y<2;y++)
for(x=0;x<20;x++)
{array[y][x]=-1;}//初始化为-1
intseque[20]={0};//访问序列
cout<<"putinpagenumb:
";
cin>>pagenum;
cout<<"putinxulie(input-1end):
";
for(inti=0;i<20;i++)
{
intnum;
cin>>num;
if(num!
=-1)
{
seque[i]=num;
total++;//总共序列数
}
else
{seque[i]=num;break;}
}
cout<<"tatalnumberis"<intj=0;
for(i=0;i{
if(i{
array[0][i]=seque[i];
cout<<"yemian"<cout<<"noethexuelieis";
for(intj=0;j{
cout<cout<<"(-1standfornothing)"<}
cout<}//xiuliehao小于页号结束
intkk=0;
for(i=pagenum;i{
intflag=0;
for(intk=0;k{
if(array[0][k]==seque[i])
{flag=1;break;}
}
cout<if(flag==1)
{cout<<"yemian"<cout<<"nowthexuelieis";
for(intj=0;j{cout<}
cout<if(flag==0)
{
inttem=array[0][kk];
array[0][kk]=seque[i];
cout<<"yemian"<cout<<"lackpage"<cout<<"noethexuelieis";
for(intj=0;j{cout<cout<kk++;
lacknumber++;//缺页数
if(kk==pagenum)
{kk=0;}
}
}
cout<<"lack="<<}
5.实验运行结果:
五思考题。
请求分页存储管理每次调入和换出的都是固定长度的页面,相比较请求分段存储管理比较简单,因此请求分页比较常用。
在请求分页管理中需要有页表机制,地址变换机构以及缺页中断机制的支持。