资源描述
第2部分、请求分页式存储管理的地址转换过程实现:
●基本要求:在第1部分实验基础上实现进程的分页式内存分配和地址转换过程,并进一步实现请求分页式存储分配和地址转换过程。页面置换算法至少应实现先进先出(FIFO)、最近最久未使用(LRU)等算法。
●参考学时:16学时
●实验提示:
1、 建立一个位示图,用来模拟内存的分配情况,位示图的位数与设定的物理块个数相同。程序启动时可利用一组随机0和1填充位示图,表示内存已被占用情况。
假设内存容量为64K,块大小为1K,则共有64个块,对应的位示图可能的值如下:
第0字节
1 0 1 1 0 0 1 1
第2字节
1 1 1 0 0 1 1 1
第4字节
0 0 0 1 1 1 1 1
第6字节
1 1 1 1 1 0 0 0
第1字节
0 1 1 0 1 1 0 0
第3字节
1 0 0 0 0 1 1 1
第5字节
0 1 1 1 0 0 1 1
第7字节
0 0 0 0 0 0 0 1
该位示图表示内存的2(0字节第2位)、3(0字节第3位)、6(0字节第6位)、8(1字节第0位)、9(1字节第1位)、12(1字节第4位)、15(1字节第7位)…等块没有被占用。
2、 创建进程时输入进程大小,并根据程序中设定的物理块大小为进程分配物理块,同时建立页表。例如,在上图基础上,若要建立一个大小为5000字节的进程,则:
l 计算出该进程共有“向上取整(5000/1024)=5”个页,需要占用5个内存块;
l 建立空的页表,即长度为5的一维整数数组;
l 从位示图中找出前5个“0”位在整个位示图中的位置号(即i字节j位为0,则该位的位置为8*i+j),并将这些号依次填入页表中,同时把前5个“0”改为“1”,以示对应内存块已经分配。
3、 输入当前执行进程所要访问的逻辑地址,并将其转换成相应的物理地址。
4、 进程退出时,根据其页表内容向位示图反向回填“1”。
5、 扩充页表,将其变成支持请求和置换功能的二维页表(增加存在位等)。创建进程时可装入固定的前三页(或键盘输入初始装入页数,不同进程的装入个数可以不同),其余页装入到置换空间内(置换空间大小应为内存空间大小的1.5倍,对其还需建立独立的位示图)。
6、 分别采用FIFO和LRU置换算法对地址转换过程中遇到的缺页现象进行页面置换,可将多次地址转换过程中所涉及到的页号视为进程的页面访问序列,从而计算置换次数和缺页率。
import java.util.Vector;
import java.io.*;
class Process{
Page []PageTable;
Vector<Page> PageQueue;
private int size;
private int Pagecount;
private String name;
double visit;
double replacement;
public void setPage(Page []PageTable) {
this.PageTable=new Page[PageTable.length];
for(int i=0;i<PageTable.length;i++) {
this.PageTable[i]=PageTable[i];
}
}
public int getPageBlock(int PageNum) {
return PageTable[PageNum].getBlockNum();
}
public void setSize(int size) {
this.size=size;
}
public void setPagecount(int Pagecount) {
this.Pagecount=Pagecount;
}
public int getPagecount() {
return Pagecount;
}
{
visit=0;
replacement=0;
}
public Process() {
}
public Process(String name){
this.name=name;
}
public String toString(){
return name;
}
}
class Page {
int flag;
int blockNum;
int writed;//xiu gai wei
int accessfield;//fang wen zi duan
int swapsapce_blockno;//wai cun dizhi
int t;
{
blockNum=0;
writed=0;
accessfield=0;
t=0;
}
public Page() {
flag=1;
swapsapce_blockno=-1;
}
public Page(int flag,int swapsapce_blockno) {
this.flag=flag;
this.swapsapce_blockno=swapsapce_blockno;
}
public int getBlockNum() {
return blockNum;
}
public int getFlag() {
return flag;
}
}
class OS2 {
public static Vector<Process> ready,blocked;
public static Process running;
public static BufferedReader br;
static int [][]a=new int[8][8];
static int[][]d=new int[10][10];//置换空间
static int count=0;
public OS2() {
ready=new Vector<Process>();
blocked=new Vector<Process>();
br=new BufferedReader(new InputStreamReader(System.in));
for(int i=0;i<a.length;i++) {
for(int j=0;j<a[i].length;j++) {
if(Math.random()<0.5) {
a[i][j]=0;
}
else {
a[i][j]=1;
}
}
}
for(int i=0;i<d.length;i++) {
for(int j=0;j<d[i].length;j++) {
if(Math.random()<0.5) {
d[i][j]=0;
}
else {
d[i][j]=1;
}
}
}
System.out.println("位示图----------------");
print(a);
System.out.println("置换空间--------------");
print(d);
}
public static void go() {
while(true){
System.out.println("=======================================================================");
System.out.println("1:进程创建 ");
System.out.println("2:进程到时 ");
System.out.println("3:进程阻塞 ");
System.out.println("4:进程唤醒 ");
System.out.println("5:进程结束 ");
System.out.println("6:逻辑地址转换为物理地址 ");
System.out.println("7:查看页表");
System.out.println("8:显示位示图和置换空间");
System.out.println("9:查看置换次数和缺页率");
System.out.println("0:退出-->");
try{
int i=Integer.parseInt(br.readLine());
switch(i){
case 0:
System.exit(0);
case 1:
createNewProcess();
break;
case 2:
switchCurrentProcess();
break;
case 3:
blockCurrentProcess();
break;
case 4:
wakeupBlockedProcess();
break;
case 5:
terminateCurrentProcess();
break;
case 6:
transform();
break;
case 7:
showPage();
break;
case 8:
System.out.println("位示图----------------");
print(a);
System.out.println("置换空间--------------");
print(d);
break;
case 9:
look();
break;
}
}
catch(Exception e){
System.out.println(e);
}
System.out.println("执行进程:"+(running==null?"none":running));
System.out.print("就绪进程:");
printList(ready);
System.out.print("阻塞进程:");
printList(blocked);
}
}
public static void printList(Vector v){
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i)+"\t");
System.out.println();
}
public static void createNewProcess(){
try{
System.out.print("进程名称:");
String name=br.readLine();
Process process=new Process(name);
ready.add(process);
System.out.print("进程大小:");
double size=Integer.parseInt(br.readLine());
int numPage=0;
numPage=(int)Math.ceil(size/1024);
process.setPagecount(numPage);
Page []P=new Page[numPage];
process.PageQueue=new Vector<Page>();
st: for(int i=0;i<a.length;i++) {
for(int j=0;j<a[i].length;j++) {
if(a[i][j]==0) {
if(count<3) {
//Page p1=new Page();
//P[count]=p1;
P[count]=new Page();
P[count].blockNum=8*i+j;
process.PageQueue.add(P[count]);
P[count].t=3-count;
count++;
a[i][j]=1;
if(count==numPage) {
break st;
}
}
else {
for(int m=0;m<d.length;m++) {
for(int n=0;n<d[m].length;n++) {
if(d[m][n]==0) {
//Page p2=new Page();
//P[count]=p2;
P[count]=new Page(0,-1);
P[count].blockNum=-1;
P[count].swapsapce_blockno=8*m+n;
count++;
d[m][n]=1;
if(count==numPage) {
count=0;
break st;
}
}
}
}
}
}
}
}
if(running==null){
running=(Process)ready.elementAt(0);
ready.removeElementAt(0);
}
process.setPage(P);
}
catch(Exception e){
System.out.println(e);
}
}
public static void switchCurrentProcess(){
if(running!=null)
ready.add(running);
if(ready.size()>0){
running=(Process)ready.elementAt(0);
ready.removeElementAt(0);
}
else
running=null;
}
public static void blockCurrentProcess(){
if(running!=null) {
blocked.add(running);
}
if(ready.size()>0) {
running=(Process)ready.elementAt(0);
ready.removeElementAt(0);
}
else {
running=null;
}
}
public static void wakeupBlockedProcess() {
if(blocked.size()>0){
//running=(Process)blocked.elementAt(0);
ready.add((Process)blocked.elementAt(0));
blocked.removeElementAt(0);
if(running==null) {
running=(Process)ready.elementAt(0);
ready.removeElementAt(0);
}
}
else {
//blocked=null;
}
}
public static void terminateCurrentProcess() {
whileExit();
if(running!=null) {
running=null;
}
if(ready.size()>0) {
running=(Process)ready.elementAt(0);
ready.removeElementAt(0);
}
else if(blocked.size()>0){
running=(Process)blocked.elementAt(0);
blocked.removeElementAt(0);
}
else {
running=null;
}
}
public static void transform() {
try {
if(running!=null) {
System.out.print("输入逻辑地址:");
int LogicAdds=Integer.parseInt(br.readLine());
int PageNumber=LogicAdds/1024;
if(PageNumber>running.getPagecount()-1) {
while(true) {
//if(PageNumber>running.getPagecount()-1) {
System.out.println("逻辑地址超出范围,请重新输入:");
LogicAdds=Integer.parseInt(br.readLine());
PageNumber=LogicAdds/1024;
if(PageNumber<=running.getPagecount()-1) {
break;
}
//}
}
}
int offset=LogicAdds%1024;
int PageBlockNum=running.getPageBlock(PageNumber);
++running.PageTable[PageNumber].accessfield;
++running.visit;
if(running.PageTable[PageNumber].getFlag()==0) {
++running.replacement;
System.out.println("请选择你所想要置换的算法(提示:1代表FIFO算法,2代表LRU算法):");
int ch=Integer.parseInt(br.readLine());
if(ch==1) {
System.out.println("正在FIFO置换算法,对地址进行转换");
Fifo(PageNumber);
}
else {
System.out.println("正在LRU置换算法,对地址进行转换");
Lru(PageNumber);
}
int PhyAdds=(running.getPageBlock(PageNumber))*1024+offset;
System.out.println("物理地址:"+PhyAdds);
}
else {
int PhyAdds=(running.getPageBlock(PageNumber))*1024+offset;
System.out.println("物理地址:"+PhyAdds);
}
}
else {
System.out.println("no running process");
}
}
catch(Exception e) {
System.out.println(e);
}
}
public static void whileExit() {
for(int i=0;i<running.PageTable.length;i++) {
if(running.PageTable[i].flag==1) {
int m=running.PageTable[i].blockNum/8;
int n=running.PageTable[i].blockNum%8;
a[m][n]=0;
}
else {
int m=running.PageTable[i].swapsapce_blockno/8;
int n=running.PageTable[i].swapsapce_blockno%8;
d[m][n]=0;
}
}
}
public static void Fifo(int PageNumber) {
running.PageTable[PageNumber].blockNum=((Page)running.PageQueue.elementAt(0)).blockNum;
st:for(int i=0;i<d.length;i++) {
for(int j=0;j<d[i].length;j++) {
if(d[i][j]==0&&running.PageQueue.size()>0) {
d[i][j]=1;
((Page)running.PageQueue.elementAt(0)).flag=0;
((Page)running.PageQueue.elementAt(0)).blockNum=-1;
((Page)running.PageQueue.elementAt(0)).writed=0;
((Page)running.PageQueue.elementAt(0)).accessfield=0;
((Page)running.PageQueue.elementAt(0)).swapsapce_blockno=8*i+j;
((Page)running.PageQueue.elementAt(0)).t=0;
running.PageQueue.removeElementAt(0);
running.PageQueue.add(running.PageTable[PageNumber]);
break st;
}
}
}
//sb:for(int m=0;m<a.length;m++) {
// for(int n=0;n<a[m].length;n++) {
// if(a[m][n]==0) {
//a[m][n]=1;
running.PageTable[PageNumber].flag=1;
//running.PageTable[PageNumber].blockNum=8*m+n;
running.PageTable[PageNumber].writed=0;
//++running.PageTable[q].accessfield;
//running.PageTable[q].swapsapce_blockno=8*m+n;
// break sb;
//}
// }
// }
}
public static void Lru(int PageNumber) {//process.PageTable[count].t
int k=getPageTime();
st:for(int i=0;i<d.length;i++) {
for(int j=0;j<d[i].length;j++) {
if(d[i][j]==0) {
d[i][j]=1;
running.PageTable[k].flag=0;
running.PageTable[k].blockNum=-1;
running.PageTable[k].writed=0;
running.PageTable[k].accessfield=0;
running.PageTable[k].swapsapce_blockno=8*i+j;
running.PageTable[k].t=1;
break st;
}
}
}
sb:for(int m=0;m<a.length;m++) {
for(int n=0;n<a[m].length;n++) {
if(a[m][n]==0) {
a[m][n]=1;
running.PageTable[PageNumber].flag=1;
running.PageTable[PageNumber].blockNum=running.PageTable[k].blockNum;
running.PageTable[PageNumber].writed=0;
//++running.PageTable[q].accessfield;
//running.PageTable[q].swapsapce_blockno=8*m+n;
break sb;
}
}
}
for(int i=0;i<running.PageTable.length;i++) {
if(i!=k) {
++running.PageTable[i].t;
}
}
}
public static int getPageTime() {
int max=running.PageTable[0].t;
int place=0;
for(int i=0;i<running.PageTable.length;i++) {
if(max<running.PageTable[i].t) {
max=running.PageTable[i].t;
place=i;
}
}
return place;
}
public static void print(int [][]a) {
for(int i=0;i<a.length;i++) {
for(int j=0;j<a[i].length;j++) {
System.out.print(" "+a[i][j]);
}
System.out.println();
}
}
public static void showPage() {
if(running==null) {
System.out.println("no running process");
return;
}
System.out.println("页号 "+"块号 "+"状态位 "+" 修改位 "+" 访问字段 "+"外存地址 ");
for(int i=0;i<running.PageTable.length;i++) {
System.out.print(i);
System.out.print(" "+running.PageTable[i].blockNum);
System.out.print(" "+running.PageTable[i].flag);
System.out.print(" "+running.PageTable[i].writed);
System.out.print(" "+running.PageTable[i].accessfield);
System.out.println(" "+running.PageTable[i].swapsapce_blockno);
}
}
public static void look() {
System.out.println("置换次数:"+running.replacement);
System.out.println("访问次数:"+running.visit);
if(running.visit!=0.0) {
System.out.println("缺页率"+(running.replacement*100)/running.visit+"%");
}
System.out.println("缺页率akjsnala5ds435ax1");
}
public static void main(String[]args) {
new OS2().go();
}
}
3、通过活动,使学生养成博览群书的好习惯。
B比率分析法和比较分析法不能测算出各因素的影响程度。√
C采用约当产量比例法,分配原材料费用与分配加工费用所用的完工率都是一致的。X
C采用直接分配法分配辅助生产费用时,应考虑各辅助生产车间之间相互提供产品或劳务的情况。错
C产品的实际生产成本包括废品损失和停工损失。√
C成本报表是对外报告的会计报表。×
C成本分析的首要程序是发现问题、分析原因。×
C成本会计的对象是指成本核算。×
C成本计算的辅助方法一般应与基本方法结合使用而不单独使用。√
C成本计算方法中的最基本的方法是分步法。X
D当车间生产多种产品时,“废品损失”、“停工损失”的借方余额,月末均直接记入该产品的产品成本
中。×
D定额法是为了简化成本计算而采用的一种成本计算方法。×
F“废品损失”账户月末没有余额。√
F废品损失是指在生产过程中发现和入库后发现的不可修复废品的生产成本和可修复废品的修复费用。X
F分步法的一个重要特点是各步骤之间要进行成本结转。(√)
G各月末在产品数量变化不大的产品,可不计算月末在产品成本。错
G工资费用就是成本项目。(×)
G归集在基本生产车间的制造费用最后均应分配计入产品成本中。对
J计算计时工资费用,应以考勤记录中的工作时间记录为依据。(√)
J简化的分批法就是不计算在产品成本的分批法。(×)
J简化分批法是不分批计算在产品成本的方法。对
J加班加点工资既可能是直接计人费用,又可能是间接计人费用。√
J接生产工艺过程的特点,工业企业的生产可分为大量生产、成批生产和单件生产三种,X
K可修复废品是指技术上可以修复使用的废品。错
K可修复废品是指经过修理可以使用,而不管修复费用在经济上是否合算的废品。X
P品种法只适用于大量大批的单步骤生产的企业。×
Q企业的制造费用一定要通过“制造费用”科目核算。X
Q企业职工的医药费、医务部门、职工浴室等部门职工的工资,均应通过“应付工资”科目核算。X
S生产车间耗用的材料,全部计入“直接材料”成本项目。X
S适应生产特点和管理要求,采用适当的成本计算方法,是成本核算的基础工作。(×)
W完工产品费用等于月初在产品费用加本月生产费用减月末在产品费用。对
Y“预提费用”可能出现借方余额,其性质属于资产,实际上是待摊费用。对
Y引起资产和负债同时减少的支出是费用性支出。X
Y以应付票据去偿付购买材料的费用,是成本性支出。X
Y原材料分工序一次投入与原材料在每道工序陆续投入,其完工率的计算方法是完全一致的。X
Y运用连环替代法进行分析,即使随意改变各构成因素的替换顺序,各因素的影响结果加总后仍等于指标的总差异,因此更换各因索替换顺序,不会影响分析的结果。(×)
Z在产品品种规格繁多的情况下,应该采用分类法计算产品成本。对
Z直接生产费用就是直接计人费用。X
Z逐步
展开阅读全文