模拟操作系统的存储系统实验(Java语言描述)

模拟分页式存储管理中硬件的地址转换和产生缺页中断

(1)分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存,页表的格式为:
在这里插入图片描述

  • 标志——用来表示对应页是否已经装入主存,标志位=1,则表示该页已经在主存,标志位=0,则表示该页尚未装入主存。
  • 主存块号——用来表示已经装入主存的页所占的块号。
  • 在磁盘上的位置——用来指出作业副本的每一页被存放在磁盘上的位置。

(2)作业执行时,指令中的逻辑地址指出了参加运算的操作数存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式:

绝对地址=块号×块长+单元号

计算出欲访问的主存单元地址。如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。按计算出的绝对地址可以取到操作数,完成一条指令的执行。若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,由操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。

(3)设计一个“地址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。当访问的页不在主存时,则输出“*该页页号”,表示产生了一次缺页中断。该模拟程序的算法如图3-1。

在这里插入图片描述

图3-1 地址转换模拟算法

(4)假定主存的每块长度为128个字节;现有一个共七页的作业,其中第0页至第3页已经装入主存,其余三页尚未装入主存;该作业的页表为:

在这里插入图片描述

如果作业依次执行的指令序列为:

在这里插入图片描述

运行设计的地址转换程序,显示或打印运行结果。因仅模拟地址转换,并不模拟指令的执行,故可不考虑上述指令序列中的操作。

用最近最少用(LRU)页面调度算法处理缺页中断

(1)在分页式虚拟存储系统中,当硬件发出“缺页中断”后,引出操作系统来处理这个中断事件。如果主存中已经没有空闲块,则可用LRU页面调度算法把该作业中距现在最久没有被访问过的一页调出,存放到磁盘上。然后再把当前要访问的页装入该块。调出和装入后都要修改页表中对应页的标志。

在这里插入图片描述
图3-2 FIFO页面调度模拟算法

(2)LRU页面调度算法总是淘汰该作业中距现在最久没被访问过的那页,因此可以用一个数组来表示该作业已在主存的页面。数组中的第一个元素总是指出当前刚访问的页号,因此最久没被访问过的页总是由最后一个元素指出。如果主存只有四块空闲块且执行第一题中提示(4)假设的指令序列,采用LRU页面调度算法,那么在主存中的页面变化情况如下:

在这里插入图片描述

当产生缺页中断后,操作系统总是淘汰由最后一个元素所指示的页,再把要访问的页装入淘汰页所占的主存块中,页号登记到数组的第一个元素中,重新启动刚才那条指令执行。

(3)编制一个LRU页面调度程序,为了提高系统效率,如果淘汰的页在执行中没有修改过,则可不必把该页调出。参看第二题中提示(3)。模拟调度算法不实际地启动调出一页和装入一页的程序而用输出调出的页号和装入的页号来代替。把第一题中程序稍作改动,与本题结合起来,LRU页面调度模拟算法如图3-3。
在这里插入图片描述
图3-3 LRU页面调度模拟算法

(4)按第一题中提示(4)的要求,建立一张初始页表,页表中为每一页增加“修改标志”位。然后按依次执行的指令序列,运行设计的程序,显示或打印每次调出和装入的页号,以及执行了最后一条指令后数组中的值。

(5)为了检查程序的正确性,可再任意确定一组指令序列,运行设计的程序,核对执行的结果。

实现代码(Java语言描述)

PageTable类:

public class PageTable {

    private int pageNumber;
    
    private int sign;
    
    private int blockNumber;
    
    private int diskNumber;
    
    private int modify;

    public PageTable(int pageNumber, int sign, int blockNumber, int diskNumber) {
        this.pageNumber = pageNumber;
        this.sign = sign;
        this.blockNumber = blockNumber;
        this.diskNumber = diskNumber;
    }

    public PageTable(int pageNumber, int sign, int diskNumber) {
        this.pageNumber = pageNumber;
        this.sign = sign;
        this.blockNumber = -1;
        this.diskNumber = diskNumber;
    }

    public PageTable() {}

    public int getModify() {
        return this.modify;
    }

    public void setModify(int modify) {
        this.modify = modify;
    }

    public int getPageNumber() {
        return this.pageNumber;
    }

    public int getSign() {
        return this.sign;
    }

    public int getBlockNumber() {
        return this.blockNumber;
    }

    public int getDiskNumber() {
        return this.diskNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public void setSign(int sign) {
        this.sign = sign;
    }

    public void setBlockNumber(int blockNumber) {
        this.blockNumber = blockNumber;
    }

    public void setDiskNumber(int diskNumber) {
        this.diskNumber = diskNumber;
    }

}

Operator类:

public class Operator {

    private String op;

    private int pageNumber;

    private int unitNumber;

    public Operator(String op, int pageNumber, int unitNumber) {
        this.op = op;
        this.pageNumber = pageNumber;
        this.unitNumber = unitNumber;
    }

    public int getPageNumber() {
        return this.pageNumber;
    }

    public String getOp() {
        return this.op;
    }

    public int getUnitNumber() {
        return this.unitNumber;
    }

    public String toString() {
        return "Operator{" +
                "op='" + this.op + '\'' +
                ", pageNumber=" + this.pageNumber +
                ", unitNumber=" + this.unitNumber +
                '}';
    }
}

StorageManagement类:

/**
 * 存储管理系统类
 * @author BlankSpace
 */
public class StorageManagement {

    private LinkedList<PageTable> pt = new LinkedList<>();

    private Queue<Operator> op = new LinkedList<>();

    public void readPage(File file) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            while(line != null) {
                StringTokenizer st = new StringTokenizer(line,"_");
                int pageNumber = Integer.parseInt(st.nextToken());
                int sign = Integer.parseInt(st.nextToken());
                String s = st.nextToken();
                int blockNumber = -1;
                if(!s.equals("0")) {
                    blockNumber = Integer.parseInt(s);
                }
                int diskNumber = Integer.parseInt(st.nextToken());
                pt.add(new PageTable(pageNumber, sign, blockNumber,diskNumber));
                line = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void readOperator(File file) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            while(line != null) {
                StringTokenizer st = new StringTokenizer(line,"_");
                String or = st.nextToken();
                int pageNumber = Integer.parseInt(st.nextToken());
                int unitNumber = Integer.parseInt(st.nextToken());
                op.add(new Operator(or,pageNumber,unitNumber));
                line = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void execute() {
        Operator ort = op.poll();
        while(ort != null) {
            int page = ort.getPageNumber();
            PageTable p = find(page);
            if(p.getSign() == 1) {
                System.out.println("recent page's address is : " + p.getPageNumber()*128+ort.getUnitNumber());
            } else {
                System.out.println("*pageNumber:"+ort.getPageNumber());
            }
            ort = op.poll();
        }
    }

    public PageTable find(int page) {
        PageTable p = null;
        for(PageTable obj : pt) {
            if(page == obj.getPageNumber()) {
                p = obj;
                break;
            }
        }
        return p;
    }

    public static void main(String[] args) {
        StorageManagement sm = new StorageManagement();
        File file = new File("src/PageTable.txt");
        sm.readPage(file);
        File file2 = new File("src/Operator.txt");
        sm.readOperator(file2);
        sm.execute();
    }
}

LRU类:

import java.util.*;
import java.io.*;

/**
 * LRU实现类
 * @author BlankSpace
 */
public class LRU {

    private static int LIST_SIZE = 4;

    private static int INDEX = 0;

    private static PageTable[] PAGES = new PageTable[7];

    private static PageTable[] DISK = new PageTable[1000];

    private static PageTable[] PAGE_LIST = new PageTable[7];

    private static List<Operator> OPERATORS = new ArrayList<>();

    public static void loadPage(File file) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            while(line != null) {
                StringTokenizer st = new StringTokenizer(line,"_");
                int pageNumber = Integer.parseInt(st.nextToken());
                int sign = Integer.parseInt(st.nextToken());
                String s = st.nextToken();
                int modify = Integer.parseInt(st.nextToken());
                int blockNumber = -1;
                if(!s.equals("0"))
                    blockNumber = Integer.parseInt(s);
                int diskNumber = Integer.parseInt(st.nextToken());
                PageTable page = new PageTable(pageNumber, sign, blockNumber, diskNumber);
                page.setModify(modify);
                PAGES[pageNumber] = page;
                DISK[diskNumber] = page;
                if(sign == 1) {
                    PAGE_LIST[INDEX++] = page;
                    INDEX %= LIST_SIZE;
                }
                line = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void loadOperator(File file) {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            while(line != null) {
                StringTokenizer st = new StringTokenizer(line,"_");
                String or = st.nextToken();
                int pageNumber = Integer.parseInt(st.nextToken());
                int unitNumber = Integer.parseInt(st.nextToken());
                OPERATORS.add(new Operator(or, pageNumber, unitNumber));
                line = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void lru(File page, File op) {
        loadPage(page);
        loadOperator(op);
        List<PageTable> pgs = new ArrayList<>();
        for(PageTable p : PAGE_LIST) {
            if(p != null) {
                pgs.add(p);
            }
        }
        for(Operator or : OPERATORS) {
            while(true) {
                int pageNumber = or.getPageNumber();
                PageTable p = PAGES[pageNumber];
                if(p == null || p.getSign() != 1) {
                    PageTable localPage = pgs.get(pgs.size()-1);
                    if(localPage.getModify() == 1) {
                        System.out.println("OUT : " + INDEX);
                    }
                    pgs.add(0, p);
                    System.out.println("IN : " + pageNumber);
                    p.setSign(1);
                    p.setModify(0);
                    INDEX = (INDEX + 1) % LIST_SIZE;
                    continue;
                }else {
                    int address = PAGES[pageNumber].getPageNumber()*128 + PAGES[pageNumber].getPageNumber() +
                            or.getUnitNumber();
                    if(or.getOp().equals("s")) {
                        p.setModify(1);
                    }
                    System.out.println("recent page's address is : " + address);
                    break;
                }
            }
        }

    }

    public static void main(String[] args) {
        File pageTable = new File("src/PageTable2.txt");
        File operator  = new File("src/Operator.txt");
        lru(pageTable, operator);
    }

}

Operator.txt:

+_0_070
+_1_050
*_2_015
s_3_021
l_0_056
-_6_040
<<_4_053
+_5_023
s_1_037
l_2_078
+_4_001
s_6_084

PageTable.txt:

0_1_5_011
1_1_8_012
2_1_9_013
3_1_1_021
4_0_0_022
5_0_0_023
6_0_0_121

PageTable2.txt:

0_1_5_0_011
1_1_8_0_012
2_1_9_0_013
3_1_1_0_021
4_0_0_0_022
5_0_0_0_023
6_0_0_0_121
发布了373 篇原创文章 · 获赞 632 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/104087263
今日推荐