最近操作系统课程实践要求,我们模拟页式存储管理,起初自己很没有思路,但是在详细的画出整个的流程的时候自己还是发现了一些规律,并且发现可以数组和队列进行模拟,我在自己写程序的时候用的是数组模拟的,当然在程序中,也会有很多的数组表示各种要记录的东西,这就要求你对页式存储管理要相当的熟悉。
这里我简单的讲述一下其中需要模拟的相关信息
1)首先需要将逻辑地址转换为对应的页号以及页内位移(这里我默认页面大小是1024,页面数为5)
例如:
830/1024=0......830
1234/1024=1......210
3333/1024=3......261
2456/1024=2......408
3500/1024=3......428
5678/1024=5......558
1245/1024=1......221
200/1024=0......200
4560/1024=4......464
1333/1024=1......309
上边的计算就是在记录每一个逻辑地址相对应的页面号以及页内位移。程序是采用输入逻辑地址,这就需要一个数组进行逻辑地址的记录,计算出的页号和页内位移需要两个数组进行记录。为了后边的编写程序时候方便,建议大家编程时将相关的变量名进行起名的时候尽量用其英文代替,这样在以后进行讲解的时候也帮助自己理解。
你还要判断你输入的逻辑地址是否越界,当你输入页面大小,以及页面数的时候就是确定了总的大小,如果逻辑地址超过了页面大小*页面数量就是代表越界。我在程序里边就是进行简单的打印越界信息,进行输出。(上边的5678就已经发生了越界 5678>5*1024)
在这里打印出页号,页内位移相关信息(是已经排除了越界的逻辑地址)
页号 | 页内位移 |
0 | 830 |
1 | 210 |
3 | 261 |
2 | 408 |
3 | 428 |
1 | 221 |
0 | 200 |
4 | 464 |
1 | 309 |
以上表格显示就是最后打印出来的输入的逻辑地址对应的页号及页内位移。我是模拟页式存储管理,采用先进先出算法。
根据表格就可以得到访问序列就是0,1,3,2,3,1,0,4,1
根据所学的知识采用先进先出算法(FIFO)模拟替换情况
访问序列 | 0 | 1 | 3 | 2 | 3 | 1 | 0 | 4 | 1 |
物理块1 | 0 | 0 | 0 | 2T | 2 | 2 | 2 | 2 | 1T |
物理块2 | 1 | 1 | 1 | 1 | 1 | 0T | 0 | 0 | |
物理块3 | 3 | 3 | 3 | 3 | 3 | 4T | 4 |
表格中用大写字母T表示的就是进行了替换。
由此可以得知这次访问中淘汰的页面数是 0,1,3,2,缺页次数是7
最后计算出物理地址,物理地址的计算方法 块号*页面大小 + 页内位移 在程序中做了简单的处理,从开始就是第一个对应块号为0,第二个对应1,第三个对应2,第四个对应0,依次循环对应,便可以得知相应页面对应的块号,今儿计算出物理地址。
以下是我自己写的程序,实现这一具体的过程。但是经过测试有点缺陷,就是输入的前三个访问的逻辑地址不能有相同的页面号(三个页号全不相等)
package 页式管理存储;
import java.util.*;
public class Page_test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int pageNum,pageVolume;
System.out.println("物理块数默认为3(从0起)");
System.out.println("请输入页面数:");
pageNum = sc.nextInt();
System.out.println("请输入页的大小:");
pageVolume = sc.nextInt();
System.out.println("输入次数(大于三):");
int processNum = sc.nextInt();
System.out.println("请输入各个进程的逻辑地址:");
int[] poistion = new int[processNum];
for(int i=0;i
volume){
re_count++;
System.out.println("此处发生越界中断,越界中断的逻辑地址是:" + poistion[i] + "\t处理成功!!!");
}
}
int[] blockNum = new int[poistion.length]; //记录页号
int[] blockPoistion = new int[poistion.length]; //页内位移
for(int i=0;i
pageNum ||(blockNum[i]==pageNum && blockPoistion[i]>0)){
continue;
}
System.out.println(blockNum[i] + "\t" + blockPoistion[i]);
}
//输出访问序列
System.out.println("访问序列:");
for(int i=0;i
pageNum ||(blockNum[i]==pageNum && blockPoistion[i]>0)){
continue;
}
System.out.print(blockNum[i] + " ");
}
System.out.println();
//显示缺页次数,缺页序列,缺页率
//程序中有三个物理块
int[] physical_block = new int[3];
boolean flag = false;
//i控制物理块坐标,a控制循环次数
for(int i=0,a=0;a<3;i++,a++){
if(blockNum[i]>pageNum ||(blockNum[i]==pageNum && blockPoistion[i]>0)){
//证明中断存在
i++;
}
physical_block[a] = blockNum[i];
}
//用一个新的数组记录偏移地址
int[] newPoistion_block = new int[blockNum.length-re_count];
for(int i=0,a=0;a
pageNum ||(blockNum[i]==pageNum && blockPoistion[i]>0)){
i++;
}
newPoistion_block[a] = blockPoistion[i];
}
//记录物理块地址
int[] phy_poistion = new int[blockNum.length-re_count];
int[] phy = {0,1,2};
for(int i=0;i<3;i++){
phy_poistion[i] = phy[i]*pageVolume + newPoistion_block[i];
}
//记录缺页的页面号
int[] num = new int[20];
for(int i=0;i<20;i++){
num[i] = -1;
}
//用一个新的数组记录访问序列
int[] newBlockNum = new int[blockNum.length-re_count];
for(int i=0,a=0;a
pageNum ||(blockNum[i]==pageNum && blockPoistion[i]>0)){ i++; } newBlockNum[a] = blockNum[i]; } //计算物理地址 for(int i=3,a=0;i
自己也只是简单的实现了,要想很完整的实现就要进行相关的判断,这个程序还是要完善。只是把先进先出算的思想表示出来。 这里是运行截图:
![](https://img-blog.csdn.net/20161230155223290)
![](https://img-blog.csdn.net/20161230155239040)
第一次写这么长的博客,希望对你有帮助,嘿嘿![微笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)