Linux操作系统实验存储管理试验Word格式.docx
《Linux操作系统实验存储管理试验Word格式.docx》由会员分享,可在线阅读,更多相关《Linux操作系统实验存储管理试验Word格式.docx(15页珍藏版)》请在冰豆网上搜索。
(4)每个申请或释放操作,都在屏幕上显示操作前与操作后的内存分配的对比图。
(5)实验假设申请和释放的页数都是2的整次幂。
(1)建立工作集页面模型。
(2)利用随机函数动态生成进程访问页面的序列号。
(3)实现FIFO页面淘汰算法。
(4)实现页故障率反馈模型。
2、实验目的与要求
①
(1)用C语言是实现模拟Linux系统中连续内存分配用到的伙伴对算法。
(2)通过链表的形式输出在内存申请和释放过程中内存状态的对比图。
②
(1)了解工作集模型的原理及其特点。
(2)实现页故障率反馈模型。
3、实验步骤与源程序
1.Buddyheap算法模拟
源程序。
#include<
stdio.h>
stdlib.h>
typedefstructblock
{
intsize。
intstart。
intloc。
structblock*next。
structblock*prior。
}block。
intmaxsize=512。
block*note。
block*id[10]。
voidprintmem(){
inti。
for(i=9。
i>
=0。
i--){
printf("
%d->
"
i)。
block*temp=(structblock*)malloc(sizeof(structblock))。
temp=id[i]->
next。
while(temp!
=NULL){
printf("
%d(%s)(%d)->
temp->
size,temp->
loc==1?
占用"
:
空闲"
start)。
temp=temp->
}
\n"
)。
}
}
voidinit(){
for(i=0。
i<
9。
i++){
id[i]=(structblock*)malloc(sizeof(structblock))。
id[i]->
prior=id[i]。
id[i]->
next=NULL。
note=(structblock*)malloc(sizeof(structblock))。
note->
size=maxsize。
start=0。
loc=0。
id[9]=(structblock*)malloc(sizeof(structblock))。
id[9]->
next=note。
prior=id[9]。
printmem()。
intpower(intx,inty){
intk=0,tmp=1。
for(。
k<
y。
k++){
tmp=tmp*x。
returntmp。
introot(intx,inty){
intresult=y,count=0。
while(result!
=1){
result=result/x。
count++。
returncount。
intsplit(inttempId){
block*pend=(structblock*)malloc(sizeof(structblock))。
block*cend=(structblock*)malloc(sizeof(structblock))。
block*newf=(structblock*)malloc(sizeof(structblock))。
block*newu=(structblock*)malloc(sizeof(structblock))。
pend=id[tempId]->
intflag=0,isFirst=0。
while(pend!
if(pend->
loc==0){
if(isFirst==0){
id[tempId]->
next=pend->
}else{
pend->
prior->
}
intsize=(pend->
size)/2。
intstart=pend->
start。
newu->
size=size。
start=start。
newf->
start=start+size。
prior=newu。
next=newf。
tempId--。
cend=id[tempId]。
while(cend->
next!
cend=cend->
cend->
next=newu。
prior=cend。
flag=1。
return1。
}else{
pend=pend->
isFirst++。
}
if(flag==0){
tempId=tempId+1。
if(tempId<
=9){
free(pend)。
free(cend)。
free(newu)。
free(newf)。
split(tempId)。
return-1。
intmerge(inttempId,block*first){
block*merger=(structblock*)malloc(sizeof(structblock))。
block*second=NULL。
second=id[tempId]->
intnextStart=first->
start+first->
size。
intpreStart=first->
start-first->
intflag=0,isFirst=0。
while(second!
if((second->
start==nextStart||second->
start==preStart)&
&
second->
loc==0){
merger->
size=(first->
size)+(second->
size)。
start=(first->
start)<
(second->
start)?
(first->
start):
if(first->
first->
next->
prior=first->
prior。
if((first->
prior)==first->
prior){
id[tempId]->
next=first->
if(second->
second->
prior=second->
if(isFirst==0){
next=second->
}else{
tempId++。
next=id[tempId]->
prior=id[tempId]。
if(id[tempId]->
=NULL)id[tempId]->
prior=merger。
id[tempId]->
next=merger。
9){
merge(tempId,merger)。
return0。
return1。
}else{
second=second->
isFirst++。
return1。
intfreeb(intsize){
block*first=(structblock*)malloc(sizeof(structblock))。
inttempId=root(2,size)。
first=id[tempId]->
intflag=0。
while(first!
if(first->
loc==1){
first->
flag=1。
break。
first=first->
if(flag==1){
merge(tempId,first)。
printmem()。
}else{
需要释放的内存块不存在!
intrequestb(intsize){
block*temp=(structblock*)malloc(sizeof(structblock))。
inttempId=root(2,size)。
temp=id[tempId]->
while(temp!
if(temp->
loc==0&
temp->
size==size){
temp->
loc=1。
分配成功!
printmem()。
}else{
temp=temp->
if(flag==0){
tempId++。
intrs=split(tempId)。
if(rs==-1){
printf("
没有合适的空间可分配!
requestb(size)。
return-1。
free(temp)。
intmain(){
init()。
intflag=1。
charorder。
do{
请输入命令:
(以空格相隔,示例:
r8)\n"
scanf("
%c%d"
&
order,&
if(order=='
r'
){
requestb(size)。
}elseif(order=='
f'
freeb(size)。
error!
是否继续?
(1继续,0退出):
%d"
flag)。
getchar()。
}while(flag==1)。
结果图:
2.页故障率反馈模型
malloc.h>
#defineMAX_WORKSET10
#defineWINDOW_SIZE20
intmempage=10。
intprocArray[WINDOW_SIZE]。
intwin[MAX_WORKSET][2]。
doublemaxRate=0.8,minRate=0.2。
doublecurRate。
intcur_workset=3。
intconflictCount=0。
voidprint(){
curRate=(double)conflictCount/(double)WINDOW_SIZE。
printf("
缺页故障率:
%g,故障率上限/下限:
%g/%g\n"
curRate,maxRate,minRate)。
voidchangeArray(){
WINDOW_SIZE。
i++){
procArray[i]=rand()%mempage。
进程调用页面序列:
%d|"
procArray[i])。
voidinit(){
inti,j。
//changeArray()。
MAX_WORKSET。
win[i][0]=-1。
win[i][1]=cur_workset。
voidchangePage(intnumber){
inti,flag=0。
for(i=1。
cur_workset。
if(win[flag][1]<
=win[i][1]){
flag=i。
win[flag][0]=procArray[number]。
win[flag][1]=1。
conflictCount++。
if(i!
=flag&
win[i][1]!
=-1){
win[i][1]++。
voidstep(intnumber){
inti,hit=0。
if(procArray[number]==win[i][0]){
//number++。
hit=1。
if(hit==0){
changePage(number)。
voidrun(){
conflictCount=0。
changeArray()。
step(i)。
冲突次数:
%d,"
conflictCount)。
voidfeedback(){
if(curRate>
maxRate){
cur_workset++。
}elseif(curRate<
minRate){
cur_workset--。
charquit。
run()。
print()。
feedback()。
输入任意字符继续,q退出\n"
%c"
quit)。
}while(quit!
='
q'
4、结果分析与实验体会
存储管理是操作系统中最重要的组成部分之一。
在早期计算时代,由于人们所需要的内存数目远远大于物理内存,人们设计出了各种各样的策略来解决此问题,其中最成功的是虚拟内存技术。
它使得系统中为有限物理内存竞争的进程所需内存空间得到满足。
我们以BuddyHeap算法为例,实现模拟Linux系统中连续内存分配。
BH算法具有速度快的明显特点,同时解决了外碎片问题,但带来内碎片,这是由于实际请求一般不能恰好与2i相对应,此时必须向上取整。
对于更大块的请求内碎片的浪费更严重。
为此Linux将剩余的内碎片按2j整数次幂切片并由二次分配器进行单独管理。
此外当进程物理空间不要求连续时,内存分配由第三分配器完成。
此外,这个实验还需要很好的理解FIFO算法,这是最简单的页面淘汰算法,在实现时,对应每一个页面需要有一个调入时间,该时间可设在内存中并用软件记录,不过最好设在寄存器中并由硬件记录。
当内存空间紧张时,调入时间最早的页面将被淘汰。
FIFO算法易于理解和编程,但它的效率不高。
被置换的页面可能存有一个初始化程序段,很早以前曾用到,以后不会再用到;
但也可能存有一组经常访问的全局变量,初始化时被调入内存,在整个程序运行过程中都将会用到。
这次实验难点在理论方面,在理解了之后操作比较顺利。