計算機操作系統:實驗三存儲管理程序設計

一、目的和要求

  • 目的

存儲管理的主要功能之一是合理地分配主存空間。請求頁式管理是一種常用的虛擬存儲管理技術。

本實驗的目的是通過請求頁式存儲管理中頁面置換算法的模擬設計,來了解虛擬存儲技術的特點,掌握請求頁式存儲管理的頁面置換算法。

  • 要求

模擬頁式虛擬存儲管理中硬件的地址轉換和缺頁中斷的處理過程,並用先進先出調度算法(FIFO)處理缺頁中斷。

二、提示

  1. 爲了裝入一個頁面而必須調出一頁時,如果被選中調出的頁面在執行中沒有修改過,則不必把該頁重新寫到磁盤上(因磁盤上已有副本)。因此,在頁表中可以增加是否修改過的標誌,當執行“存”指令、“寫”指令時把對應頁的修改標誌置成“1”,表示該頁修改過,否則爲“0”,表示該頁未修改過。頁表格式如表3-1所示。

 

表3-1   頁表格式

  頁  號

  標  志

   主存塊號

   修改標誌

   磁盤上的位置

 

 

 

 

 

 

 

 

 

  1. 設計一個地址轉換程序來模擬硬件的地址轉換和缺頁中斷處理過程。當訪問的頁在主存時則形成絕對地址,但不去模擬指令的執行,可用輸出轉換後的絕對地址來表示一條指令已完成。當訪問的頁不在主存時則輸出“*該頁頁號”來表示硬件產生了一次缺頁中斷。模擬地址轉換的程序流程如圖3-1所示。
  2. 編制一個FIFO頁面調度程序。FIFO頁面調度算法總是先調出作業中最先進入主存的那一頁,因此,可以用一個數組來構成頁號隊列。數組中每個元素是該作業已在主存的頁面號,假定分配給作業的主存塊數爲m,且該作業開始的m頁已裝入主存,則數組可由m個元素組成:

P[0],P[1],…,P[m-1]

它們的初值爲

P[0]∶=0,P[1]∶=1,…,P[m-1]∶= m-1

用一指針k指示當要裝入新頁時應調出的頁在數組的位置,k的初值爲“0”。

 

 

當產生缺頁中斷後,操作系統總是選擇P[k]所指出的頁面調出,然後執行

P[k]∶=要裝入的新頁頁號

k∶=(k+1)mod m

在實驗中不必實際地啓動磁盤執行調出一頁和裝入一頁的工作,而用輸出“OUT調出的頁號”和“IN要裝入的新頁頁號”來模擬一次調出和裝入的過程。模擬程序的流程見圖3-1。

  1. 假定主存的每塊長度爲1024個字節,現有一個共7頁的作業,其副本已在磁盤上。系統爲該作業分配了4塊主存塊,且該作業的第0頁至第3頁已經裝入主存,其餘3頁尚未裝入主存,該作業的頁表見表3-2所示。

 

表3-2    作業的頁表

   頁號

   標誌

   主存塊號

   修改標誌

   在磁盤上的位置

    0

    1

      5

      0

         011

    1

    1

      8

      0

         012

    2

    1

      9

      0

         013

    3

    1

      1

      0

         021

    4

    0

 

      0

         022

    5

    0

 

      0

         023

    6

    0

 

      0

         121

 

如果該作業依次執行的指令序列如表3-3所示。 

 

表3-3   作業依次執行的指令序列

   操作

   頁號

  頁內地址

   操作

   頁號

  頁內地址

    +

     0

    070

   移位

     4

    053

    +

     1

    050

    +

     5

    023

    ×

     2

    015

    存

     1

    037

    存

     3

    021

    取

     2

    078

    取

     0

    056

    +

     4

    001

    -

     6

    040

    存

     6

    084

 

依次執行上述的指令序列來調試你所設計的程序(僅模擬指令的執行,不必考慮指令序列中具體操作的執行)

  1. 爲了檢查程序的正確性,可自行確定若干組指令序列,運行設計的程序,覈對執行結果。
#include<iostream>
#include<queue>
#include<map>
using namespace std;
#define PAGE_NUM 7
#define BLOCK_NUM 4
struct PageTable{
	int id;
	int flag;
	int mainMemory;
	int isModefy;
	int diskPos; 
}pageTable[PAGE_NUM];
int mainBlock[BLOCK_NUM]={5,8,9,1};
int order[BLOCK_NUM];
int page[BLOCK_NUM];
void printInfo()
{
	cout<<"頁號\t\t\t標誌\t\t\t主存塊號\t\t修改標誌\t\t磁盤位置"<<endl;
	for(int i=0;i<PAGE_NUM;i++){
		cout<<pageTable[i].id<<"\t\t\t"<<pageTable[i].flag
		<<"\t\t\t"<<pageTable[i].mainMemory<<"\t\t\t"<<pageTable[i].isModefy<<"\t\t\t"<<pageTable[i].diskPos<<endl;
	}
}

void init(){
	for(int i=0;i<BLOCK_NUM;i++){
		order[i] = i;
		page[i] = i;
	}
	for(int i=0;i<PAGE_NUM;i++){
//		freopen("in.txt","r",stdin);
		cin>>pageTable[i].id>>pageTable[i].flag>>pageTable[i].mainMemory>>pageTable[i].isModefy>>pageTable[i].diskPos;
	}
}



int isHit(int pageId){
	for(int i=0;i<BLOCK_NUM;i++){
		if(pageTable[i].flag == 1){
			cout<<"命中"<<endl;
			return i;
		}
	}
	return -1;
}
void fifo(int pageId){
	cout<<"調出頁"<<pageTable[page[order[0]]].id<<"釋放主存塊"<<mainBlock[page[order[0]]]<<endl;
	pageTable[page[order[0]]].flag = 0; 
	pageTable[page[order[0]]].isModefy = 0;
	pageTable[page[order[0]]].flag = 0;
	pageTable[page[order[0]]].mainMemory = -1;
	if(pageTable[page[order[0]]].isModefy == 1){
	
		cout<<"該調出頁已經被修改,需要重新寫出"<<endl;
		
	}
	int t = order[0];
	for(int i=1;i<BLOCK_NUM;i++){
		order[i-1] = order[i];
	}
	order[BLOCK_NUM-1] = t;
//	調入
	page[order[BLOCK_NUM-1]] = pageId;
	pageTable[pageId].flag = 1;
	pageTable[pageId].mainMemory = mainBlock[order[BLOCK_NUM-1]];
}
void execute(){
	char op;
	while(cin>>op&&op!='#'){
		int pageId;
		int pageAddress;
		cin>>pageId>>pageAddress;
		if(pageId >= PAGE_NUM){
			cout<<"頁號大於頁數,請重新輸入"<<endl;
			continue;
		}
		
		if(pageTable[pageId].flag == 1){
			cout<<"經地址變換後,該指令的形式爲"<<endl<<endl;
			cout<<"操作數"<<"\t"<<"頁號"<<"\t"<<"絕對地址"<<endl;
			cout<<op<<"\t"<<pageId<<"\t"<<pageAddress+pageTable[pageId].diskPos<<endl<<endl;
			if(op == 'd' || op == 'w'){
				pageTable[pageId].isModefy = 1;
			}
		}else{
			fifo(pageId);
		}
		printInfo();
	}
}
int main()
{
	init();
	execute();
	
	return 0;
 } 

For this problem ,just simulate the process of page managament.The requirement of this experiment is FIFO,which means that the page will be transfered out is which is transfered in fristly.

The datastructure is a page table ,which comprise some kinds of information.

struct PageTable{
    int id;
    int flag;
    int mainMemory;
    int isModefy;
    int diskPos; 
}pageTable[PAGE_NUM];

id -->the id of page.

flag -->identify wether the page is in mainMemory

mainMemory -->if flag == 1,then mainMemory show the block number,else display -1;

isModefy --> a flag that show the state whether the page has been modefied.

diskPos-->show the position where page in the disk(not memory);

See function init();

       just init the infomation,input 

function isHit();

       when user input a instruction ,like + 0 70.

       this function will judge wether the block 0 is in mainmemory.If so ,return a value 1,else return 0(false);

function printInfo();

       just print the information of current state ,display all infomation.

function fifo();

        this is the core function of this procedure.This function will be called when that function isHit() return a value 0,Which means there is no free block so that OS must transter out a block.

 

Red circle is my logic design,I use three arrays to realize the process.

mainBlock stroge the block bumber .

page stroge the page number ,which in the main memory.

due to the algorithm fifo,we should confirm the order of page.So I add a array name order to point the opder of page .

It may be a little difficult to comprehense other's producure.But ,come on.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章