操作系统实验三.docx
- 文档编号:28779506
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:18
- 大小:521.02KB
操作系统实验三.docx
《操作系统实验三.docx》由会员分享,可在线阅读,更多相关《操作系统实验三.docx(18页珍藏版)》请在冰豆网上搜索。
操作系统实验三
广州大学学生实验报告
开课学院及实验室:
计算机学院,电子信息楼416A室2014年11月20日
学院
计算机科学与教育软件学院
年级/专业/班
计科122
姓名
庞彬
学号
1206100022
实验课程名称
操作系统
成绩
实验项目名称
实验三内存管理实验
指导老师
张艳玲
一、实验目的
通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
了解linux环境下如何实现内存的分配与回收。
二、实验内容
(一)内存管理实验1:
常用页面置换算法模拟实验
设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
1、最佳淘汰算法(OPT)
2、先进先出的算法(FIFO)
3、最近最久未使用算法(LRU)
4、最不经常使用算法(LFU)
5、最近未使用算法(NUR)
命中率=1-页面失效次数/页地址流长度
(二)内存管理实验2:
Linux下的内存分配与回收的管理
在Linux环境下利用下列系统调用malloc(),free()编写一段程序实现内存分配与回收的管理。
要求:
返回已分配给变量的内存地址;
返回释放后的内存地址;
释放已分配的内存空间后,返回释放内存后未使用内存的大小。
三、实验设备
安装带Linux操作系统的电脑一台。
四、实验程序实现及结果分析
(一)内存管理实验1:
常用页面置换算法模拟实验
实验程序如下:
#defineTRUE1
#defineFALSE0
#defineINVALID-1
#defineNULL0
#definetotal_instruction320/*指令流长*/
#definetotal_vp32/*虚页长*/
#defineclear_period50/*清0周期*/
typedefstruct/*页面结构*/
{
intpn,pfn,counter,time;
}pl_type;
pl_typepl[total_vp];/*页面结构数组*/
structpfc_struct{/*页面控制结构*/
intpn,pfn;
structpfc_struct*next;
};
typedefstructpfc_structpfc_type;
pfc_typepfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;
intdiseffect,a[total_instruction];
intpage[total_instruction],offset[total_instruction];
intinitialize(int);
intFIFO(int);
intLRU(int);
intLFU(int);
intNUR(int);
intOPT(int);
intmain()
{
ints,i,j;
srand(10*getpid());/*由于每次运行时进程号不同,故可用来作为初始化随机数队列的“种子”*/
s=(float)319*rand()/32767/32767/2+1;//
for(i=0;i { if(s<0||s>319) { printf("Wheni==%d,Error,s==%d\n",i,s); exit(0); } a[i]=s;/*任选一指令访问点m*/ a[i+1]=a[i]+1;/*顺序执行一条指令*/ a[i+2]=(float)a[i]*rand()/32767/32767/2;/*执行前地址指令m'*/ a[i+3]=a[i+2]+1;/*顺序执行一条指令*/ s=(float)(318-a[i+2])*rand()/32767/32767/2+a[i+2]+2; if((a[i+2]>318)||(s>319)) printf("a[%d+2],anumberwhichis: %dands==%d\n",i,a[i+2],s); } for(i=0;i { page[i]=a[i]/10; offset[i]=a[i]%10; } for(i=4;i<=32;i++)/*用户内存工作区从4个页面到32个页面*/ { printf("---%2dpageframes---\n",i); FIFO(i); LRU(i); LFU(i); NUR(i); OPT(i); } return0; } intinitialize(total_pf)/*初始化相关数据结构*/ inttotal_pf;/*用户进程的内存页面数*/ {inti; diseffect=0; for(i=0;i { pl[i].pn=i; pl[i].pfn=INVALID;/*置页面控制结构中的页号,页面为空*/ pl[i].counter=0; pl[i].time=-1;/*页面控制结构中的访问次数为0,时间为-1*/ } for(i=0;i { pfc[i].next=&pfc[i+1]; pfc[i].pfn=i; }/*建立pfc[i-1]和pfc[i]之间的链接*/ pfc[total_pf-1].next=NULL; pfc[total_pf-1].pfn=total_pf-1; freepf_head=&pfc[0];/*空页面队列的头指针为pfc[0]*/ return0; } intFIFO(total_pf)/*先进先出算法*/ inttotal_pf;/*用户进程的内存页面数*/ { inti,j; pfc_type*p; initialize(total_pf);/*初始化相关页面控制用数据结构*/ busypf_head=busypf_tail=NULL;/*忙页面队列头,队列尾链接*/ for(i=0;i { if(pl[page[i]].pfn==INVALID)/*页面失效*/ { diseffect+=1;/*失效次数*/ if(freepf_head==NULL)/*无空闲页面*/ { p=busypf_head->next; pl[busypf_head->pn].pfn=INVALID; freepf_head=busypf_head;/*释放忙页面队列的第一个页面*/ freepf_head->next=NULL; busypf_head=p; } p=freepf_head->next;/*按FIFO方式调新页面入内存页面*/ freepf_head->next=NULL; freepf_head->pn=page[i]; pl[page[i]].pfn=freepf_head->pfn; if(busypf_tail==NULL) busypf_head=busypf_tail=freepf_head; else { busypf_tail->next=freepf_head;/*free页面减少一个*/ busypf_tail=freepf_head; } freepf_head=p; } } printf("FIFO: %6.4f\n",1-(float)diseffect/320); return0; } intLRU(total_pf)/*最近最久未使用算法*/ inttotal_pf; { intmin,minj,i,j,present_time; initialize(total_pf); present_time=0; for(i=0;i { if(pl[page[i]].pfn==INVALID)/*页面失效*/ { diseffect++; if(freepf_head==NULL)/*无空闲页面*/ { min=32767; for(j=0;j if(min>pl[j].time&&pl[j].pfn! =INVALID) { min=pl[j].time; minj=j; } freepf_head=&pfc[pl[minj].pfn];//腾出一个单元 pl[minj].pfn=INVALID; pl[minj].time=-1; freepf_head->next=NULL; } pl[page[i]].pfn=freepf_head->pfn;//有空闲页面,改为有效 pl[page[i]].time=present_time; freepf_head=freepf_head->next;//减少一个free页面 } else pl[page[i]].time=present_time;//命中则增加该单元的访问次数 present_time++; } printf("LRU: %6.4f\n",1-(float)diseffect/320); return0; } intNUR(total_pf)/*最近未使用算法*/ inttotal_pf; {inti,j,dp,cont_flag,old_dp; pfc_type*t; initialize(total_pf); dp=0; for(i=0;i {if(pl[page[i]].pfn==INVALID)/*页面失效*/ {diseffect++; if(freepf_head==NULL)/*无空闲页面*/ {cont_flag=TRUE; old_dp=dp; while(cont_flag) if(pl[dp].counter==0&&pl[dp].pfn! =INVALID) cont_flag=FALSE; else { dp++; if(dp==total_vp) dp=0; if(dp==old_dp) for(j=0;j pl[j].counter=0; } freepf_head=&pfc[pl[dp].pfn]; pl[dp].pfn=INVALID; freepf_head->next=NULL; } pl[page[i]].pfn=freepf_head->pfn; freepf_head=freepf_head->next; } else pl[page[i]].counter=1; if(i%clear_period==0) for(j=0;j pl[j].counter=0; } printf("NUR: %6.4f\n",1-(float)diseffect/320); return0; } intOPT(total_pf)/*最佳置换算法*/ inttotal_pf; {inti,j,max,maxpage,d,dist[total_vp]; pfc_type*t; initialize(total_pf); for(i=0;i {//printf("InOPTfor1,i=%d\n",i);//i=86;i=176;206;250;220,221;192,193,194;258;274,275,276,277,278; if(pl[page[i]].pfn==INVALID)/*页面失效*/ { diseffect++; if(freepf_head==NULL)/*无空闲页面*/ {for(j=0;j if(pl[j].pfn! =INVALID)dist[j]=32767;/*最大"距离"*/ elsedist[j]=0; d=1; for(j=i+1;j { if(pl[page[j]].pfn! =INVALID) dist[page[j]]=d; d++; } max=-1; for(j=0;j if(max { max=dist[j]; maxpage=j; } freepf_head=&pfc[pl[maxpage].pfn]; freepf_head->next=NULL; pl[maxpage].pfn=INVALID; } pl[page[i]].pfn=freepf_head->pfn; freepf_head=freepf_head->next; } } printf("OPT: %6.4f\n",1-(float)diseffect/320); return0; } intLFU(total_pf)/*最不经常使用置换法*/ inttotal_pf; { inti,j,min,minpage; pfc_type*t; initialize(total_pf); for(i=0;i {if(pl[page[i]].pfn==INVALID)/*页面失效*/ {diseffect++; if(freepf_head==NULL)/*无空闲页面*/ {min=32767; for(j=0;j {if(min>pl[j].counter&&pl[j].pfn! =INVALID) { min=pl[j].counter; minpage=j; } pl[j].counter=0; } freepf_head=&pfc[pl[minpage].pfn]; pl[minpage].pfn=INVALID; freepf_head->next=NULL; } pl[page[i]].pfn=freepf_head->pfn;//有空闲页面,改为有效 pl[page[i]].counter++; freepf_head=freepf_head->next;//减少一个free页面 } else pl[page[i]].counter++; } printf("LFU: %6.4f\n",1-(float)diseffect/320); return0; } 实验结果如图1-图3所示。 图1 图2 图3 从实验结果看,随着设置的空闲页面数的增加,各个算法的命中率都相对提高,其中,OPT算法命中率最高,其次为NUR,而FIFO与LRU相差无几,最低的是LFU,但每个页面执行结果有所不同。 OPT算法在执行过程中可能会发生错误。 思考题: 为什么OPT在执行时会有错误产生? OPT算法: 在将来不出现的或最晚出现的先淘汰,可以看出,它是一种对未来的假设判断,假设知道了将来要使用的页面,从而根据该情况来作出选择,但是进程是动态执行的,未来是无法预知的,所以,当碰到这种未来假设与实际不符时就会出现错误。 (一)内存管理实验2: Linux下的内存分配与回收的管理 实验程序如下: /*MALLOC.C: Thisprogramallocatesmemorywith *malloc,thenfreesthememorywithfree. */ #include #include #include #include voidmain() { int*string; /*Allocatespaceforapathname*/ string=(int*)malloc(10); if(string==NULL) printf("Insufficientmemoryavailable\n"); else { printf("Memoryspaceallocatedforpathname\n"); /*printf("string=%d\n",string);*/ cout<<"string="< free(string); printf("Memoryfreed\n"); } int*stringy; /*Allocatespaceforapathname*/ stringy=(int*)malloc(12); if(stringy==NULL) printf("Insufficientmemoryavailable\n"); else { printf("Memoryspaceallocatedforpathname\n"); /*printf("string=%d\n",string);*/ cout<<"stringy="< free(stringy); printf("Memoryfreed\n"); } } 实验结果如下图所示。 图4 第一次调用malloc,申请10个字节大小的连续内存空间,返回该内存空间的首地址string,释放后,第二次调用malloc,申请12个字节大小的内存空间,返回stringy,与string值相同。 在第一次调用并释放后,增加一句: string=NULL;发现,此时第二次调用malloc,结果是: Insufficientmemoryavailable,说明,调用malloc后返回为空。 在第二次调用malloc时,实际上并没有重新申请空间。 五、实验总结 1通过实验,了解到了linux操作系统常见的对内存进行管理的算法,认识了动态分配内存的概念。 2通过对比以上几种内存管理算法,我们了解到OPT算法的命中率最高的,其次为NUR,而FIFO与LRU相差无几,最低的是LFU。 3对OPT算法进行分析,OPT的命中率是常见的内存管理算法中最高的。 它的原理是最将晚出现的先淘汰,但是这样子常常会出现错误,因为程序是动态的,这样子无法对程序的将来的情况进行准确的判断,就不具有很好的健壮性。 4以上的内存管理算法也只是真正的系统管理的一部分,实际的情况会更加的复杂,但是常见的算法是我们深入学习的基础,所以必须熟练掌握。 5第二部分我们了解到了内存空间的释放以及调用方式。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验