转载

操作系统作业~分页式存储管理(作业)

1、 实现分页式存储管理地址转换过程,将逻辑地址转换成物理地址。

2、 在此基础上实现请求分页的地址转换;实现请求页式地址转换中出现的缺页现象中,用到的先进先出、最近最久未使用、最佳置换算法。掌握内存的分配方法和虚拟存储器的概念和原理。

利用键盘输入本模拟系统分配给作业的内存物理块个数,作业在执行过程中的页面调度次序。计算出三种算法的缺页次数和缺页率。

先说下什么是页(页面):就是将用户的程序的的地址空间分成固定大小的区域,称为”页“,或者”页面“

之后将这些页离散的放进内存中,这样解决了内存的碎片问题

记得老师上课说了下这两个概念不能混,现在区分下:

在第4章存储器管理,学习了分页式存储管理方式(是为了解决内存的碎片问题)

在第5章虚拟存储器,学习了请求分页式管理方式(除了解决碎片问题外,又“扩充”了内存的大小(虚拟))

在这里为了使得固定数目的内存来运行较多的进程,增加了调页功能和页面置换功能。

页面置换用到了三种方法

1.先进先出(FIFO),最先得到内存的最先置换它    

2最近最久未使用(LRU),和FIFO差不多,只是把命中的页面放在最不应该淘汰的位置(栈顶,或者栈低,不同的老师有不同的讲法),就是说新来的将最晚被淘汰  

3最佳置换方法,这个只是用来评估的算法,它要预测将来谁是最迟要内存的(因为它目前不用内存,先让别人用内存),把它先淘汰。

下面是流程图,你们不要嫌弃我~我真不会把流程图插进来,只好截图了(可是本姑娘已经对齐了~)

再下面是代码~你们知道怎么插入代码么~为啥我的那么难看

写代码的过程中有几个问题,我在下面用黄色笔标注出来! 编译器vs2010

有一些全局变量是想到啥就直接加的,你们看起看可能也会非常费劲。主要注意思想,看别人代码是个超级烦的事情。我很少很少很少看别人写的代码

所以我觉得我写代码就非常罗嗦,一点不简洁。这个是我第一次发这个东西,我以后写的时候尽可能注意简洁性。

你们要是有不懂的就在下面问吧~

操作系统作业~分页式存储管理(作业)

操作系统作业~分页式存储管理(作业)

#include<iostream>

#include<vector>

#include<string>

using namespace std;

typedef struct Pagetable

{

int physicalblock_No;//物理块号

int state;//状态位

}PT;

typedef struct Pagetable3

{

int physicalblock_No3;//物理块号

int state3;//状态位

}PT3;

int fifo;

int lru;

int opti;

int opt[25];//保存出现过的页号

int h=0;

PT pt[100];

PT3 pt3[100];

int COUNT;

vector<int> stack;//FIFO栈

vector<int> stack2;//LRU栈

vector<int> stack3;//optimal栈

int physical_block;//内存块数

int page_size;//页大小

int pagetable_len;//页表长度

int m[8][8];//位示图

int PageAdd;//页内地址

void Inite();//初始化位示图

void showwst();//显示位视图

void showqyl();//显示缺页率

int call_in();//调入页面

void LRU(int page_no);//

void FIFO(int page_no);//

void optimal(int pageno);

void showstack();//显示栈

void showstack2();//LRU

void showstack3();//opti

int w;

void main()

{

Inite();

int logic_add;

cout<<"输入所分配的内存块数";

cin>>physical_block;

int a;

cout<<"输入页面大小(kb)";

cin>>page_size;

cout<<"输入页表长度";

cin>>pagetable_len;

int i;

for(int i=0;i<pagetable_len;i++)//最开始页表的状态位都是0

{

pt[i].state=0;

}

int PageNo;

int count=0;

do{

COUNT++;

do

{

a=0;

cout<<"输入逻辑地址";

count=count+1;

cin>>hex>>logic_add;//我在这里是以16进制的方式输入的地址,在下面的所有代码却都默认为16进制了!!!!!为何啊?

PageNo=logic_add/(1024*page_size);//页号

if(PageNo>=pagetable_len)

{

a=1;

cout<<"越界中断请重新输入"<<endl;

}

}while(a==1);

cout<<"页号"<<PageNo<<endl;

opt[h]=PageNo;

h++;

PageAdd=logic_add%(1024*page_size);//页内地址

cout<<"页内地址"<<hex<<PageAdd<<endl;

/*if(pt[PageNo].state==0)

{

cout<<"此页不在内存!正在查找是否有剩余物理块......"<<endl;

}*/

if(stack.size()==physical_block)//栈满了

{

cout<<"FIFO"<<endl;

FIFO(PageNo);

cout<<"LRU"<<endl;

LRU(PageNo);

}

else//栈没满

{

int n=0;

for(int i=0;i<stack.size();i++)

{

if(stack[i]==PageNo)

{

cout<<"命中"<<endl;

cout<<"物理地址"<<endl<<hex<<pt[PageNo].physicalblock_No*1024+PageAdd;

n=1;

break;

}

}

if(n==0)

{

cout<<"内存有剩余,可以从位示图中分配内存(物理块号)"<<endl;

int local=call_in();//

pt[PageNo].physicalblock_No=local;//页表

cout<<"物理地址"<<endl;

cout<<hex<<local*page_size*1024+PageAdd<<endl;

stack.push_back(PageNo);

stack2.push_back(PageNo);

stack3.push_back(PageNo);

cout<<"FIFO"<<endl;

showstack();

cout<<"LRU"<<endl;

showstack2();

cout<<"最佳置换"<<endl;

showstack3();

pt[PageNo].physicalblock_No=local;

pt[PageNo].state=1;

pt3[PageNo].physicalblock_No3=local;

pt3[PageNo].state3=1;

}

}

cout<<"是否继续输入 1是 2否"<<endl;

cin>>i;

}while(i!=2);

cout<<"最佳置换"<<endl;

for(w=physical_block;w<COUNT;w++)

{

optimal(opt[w]);

}

showqyl();

system("pause");

}

void showqyl()

{ //这个代码,就是我刚才说的默认为16进制,害得我必须加上dec(10进制输出)

cout<<"FIFO"<<"缺页率:"<<dec<<fifo+physical_block<<"/"<<dec<<COUNT<<endl;

cout<<"LRU"<<"缺页率:"<<dec<<lru+physical_block<<"/"<<dec<<COUNT<<endl;

cout<<"optimal"<<"缺页率"<<dec<<opti+physical_block<<"/"<<dec<<COUNT<<endl;

}

int call_in()//位视图是8*8的

{

int loc;

for(int h=2;h<8;h++)

for(int lie=0;lie<8;lie++)

{

if(m[h][lie]==0)

{

loc=(((8*h)+lie)+1);

cout<<dec<<loc<<"号内存可以分配"<<endl;

m[h][lie]=1;

h=8;

break;

}

}

showwst();

return loc;

}

void Inite()

{

int h=2;

for(int i=0;i<2;i++)//给最开始的前2行赋值为1,系统区

{

for(int j=0;j<8;j++)

{

m[i][j]=1;

}

}

do{

int a[32];

int i=0;

long num;

num=rand()%128;

//我在想各种方式变成2进制,什么atoi  itoa  各应死了,都不如自己写一个进制转换

while(num>=1)//算出2进制数

{

a[i]=num%2;

num=num/2;

i++;

}

//不足8位在前面补0

if(i<8)

{

for(int j=i;j<=7;j++)

{

a[j]=0;

}

}

for(i=7;i>=0;i--)

{

m[h][i]=a[i];

}

h++;

}while(h<8);

for(int h=0;h<8;h++)//行

{

for(int l=0;l<8;l++)//列

{

cout<<m[h][l];

}

cout<<endl;

}

}

void FIFO(int page_no)

{

int a=0;

for(vector<int>::iterator it = stack.begin();it!=stack.end();++it)

{

if(page_no==*it)

{

cout<<"命中"<<endl;

cout<<"物理地址"<<endl<<hex<<pt[page_no].physicalblock_No*1024*page_size+PageAdd<<endl;

a=1;

break;

}

}

if(a==0)

{

fifo++;

vector<int>::iterator it = stack.begin();

pt[page_no].physicalblock_No=pt[*it].physicalblock_No;

cout<<"物理地址"<<endl;

cout<<hex<<pt[page_no].physicalblock_No*page_size*1024+PageAdd<<endl;

stack.erase(it);

stack.push_back(page_no);

pt[page_no].state=0;

}

showstack();

}

void showstack()

{

for(int i=stack.size()-1;i>=0;i--)

{

cout<<stack[i]<<endl;

}

cout<<endl;

}

void showstack2()

{

for(int i=stack2.size()-1;i>=0;i--)

{

cout<<stack2[i]<<endl;

}

cout<<endl;

}

void showstack3()

{

for(int i=stack3.size()-1;i>=0;i--)

{

cout<<stack3[i]<<endl;

}

cout<<endl;

}

void LRU(int page_no)

{

int a=0;

for(vector<int>::iterator it = stack2.begin();it!=stack2.end();++it)

{

if(page_no==*it)

{

cout<<"命中"<<endl;

cout<<"物理地址"<<endl<<hex<<pt[page_no].physicalblock_No*1024*page_size+PageAdd<<endl;

vector<int>::iterator it = stack2.begin();

stack2.erase(it);

stack2.push_back(page_no);

a=1;

break;

}

}

if(a==0)

{

lru++;

vector<int>::iterator it = stack2.begin();

pt[page_no].physicalblock_No=pt[*it].physicalblock_No;

cout<<"物理地址"<<endl;

cout<<hex<<pt[page_no].physicalblock_No*page_size*1024+PageAdd<<endl;

stack2.erase(it);

stack2.push_back(page_no);

}

showstack2();

}

void showwst()

{

for(int h=0;h<8;h++)//行

{

for(int l=0;l<8;l++)//列

{

cout<<m[h][l];

}

cout<<endl;

}

}

void optimal(int pageno)

{

int j=0;int a[25];int m=0;int flag=0;

for(int i=0;i<physical_block;i++)

{

if(stack3[i]==pageno)

{

cout<<"命中"<<endl;

cout<<"物理地址"<<endl<<hex<<pt3[pageno].physicalblock_No3*1024*page_size+PageAdd<<endl;

m=1;

break;

}

}

if(m==0)

{

int p;

opti++;//缺页次数

while(j<physical_block)

{

for(p=w+1;p<h;p++)//w为当前缺页位置位置的下一个

{

if(stack3[j]==opt[p])//2==2

{

a[stack3[j]]=p; //,a这个数组存的是页面是在第几次出现的,a[2]=9 表示2页在第9个出现的,a[6]=8;代表6这个页面是在第8次出现的,那么淘汰2这个页面

break; //写到这里我忽然想到了一个排序,计数排序,我不知道我为何会联想到这个伟大的算法

}

}

if(p==h)

{

//此页面以后都不会被使用

pt3[opt[w]].physicalblock_No3=pt3[stack3[j]].physicalblock_No3;

stack3[j]=opt[w];

cout<<"物理地址"<<endl;

cout<<hex<<pt3[opt[w]].physicalblock_No3*page_size*1024+PageAdd<<endl;

flag=1;

j=physical_block;

}

j++;

}

if(flag==0)

{

int max=0;int out;//要淘汰的页号

for(int i=0;i<20;i++)

{

if(a[i]>max)

{

out=i;

max=a[i];

}

}

for(int i=0;i<physical_block;i++)

{

if(stack3[i]==out)

{

pt3[pageno].physicalblock_No3=pt3[out].physicalblock_No3;

cout<<"物理地址"<<endl;

cout<<hex<<pt3[pageno].physicalblock_No3*page_size*1024+PageAdd<<endl;

stack3[i]=pageno;

}

}

}

}

showstack3();

}

正文到此结束
Loading...