C语言模拟实现虚拟存储管理(请求分页存储管理)
C語言模擬實現虛擬存儲管理(請求分頁存儲管理)使用FIFO算法
1)實驗目的
2)實驗內容
3)實驗基本原理和解決方案
4)數據結構、模塊劃分
5)畫出程序的基本結構框圖和流程圖(包括主程序流程圖、模塊詳細設計流程圖等),對程序的每一部分要有詳細的設計分析說明,說明設計實現所用的原理。
6)源代碼,要求格式規范,適當加注釋,以有助于說明問題為宜,注釋不少于三分之一。
7)運行的結果,要求有對結果的分析
8)參考資料
一、實驗目的
存儲管理的主要功能之一是合理的分配空間。請求分頁存儲管理是一種常用的虛擬存儲管理技術。本實驗的目的是:通過編程模擬實現請求分頁存儲管理中硬件地址轉換過程、缺頁中斷處理過程,以及先進先出頁面置換算法,加深對頁式虛擬存儲管理的理解,了解虛擬存儲技術的特點,掌握請求頁式存儲管理的頁面置換方法;通過編寫和調試地址轉換過程的模擬程序以加強對地址轉換過程的了解。
二、實驗內容
閱讀教材《計算機操作系統》第四章,掌握存儲器管理相關概念和原理。
(1)用C語言實現對分頁式存儲管理中的硬件的地址轉換和產生缺頁中斷。
(2)設計頁表。
頁式虛擬存儲系統是把作業的副本存放在磁盤上,當作業被選中時,可把作業的開始幾頁先裝入主存且啟動執行。為此,在為作業建立頁表時,應說明哪些頁已在主存,哪些頁尚未裝入主存,頁表的格式為:
頁 號 標志 主存塊號 修改標志 在磁盤上的位置
其中:
標志——用來表示對應頁是否已經裝入主存,標志位=1,則表示該頁已經在主存中,標志位=0,則表示該頁尚未裝入主存。
主存塊號——用來表示已經裝入主存的頁所占的物理塊號。
修改標志——用來表示已經裝入主存的頁是否被修改過。為,則表示該頁裝入主存后被修改過;為0,則表示該頁該頁裝入主存后未被修改過。
在磁盤上的位置——用來指出作業副本的每一頁被存放在磁盤上的位置。
可根據頁面置換算法的不同,頁表的內容可以作適當的增刪。
三、實驗基本原理和解決方案
(1)地址計算。
作業執行時,先根據指令中的邏輯地址算出參加運算的操作數存放的頁號和頁內地址,硬件的地址轉換機構按頁號查頁表,若該頁對應標志為“1”,則表示該頁已在主存,根據關系式:
絕對地址=塊號*塊長+頁內地址
計算出欲訪問的主存單元地址。按計算出的絕對地址可以取到操作數,完成一條指令的執行。若訪問的頁標志為“0”,則表示該頁不在主存,這時硬件發“缺頁中斷”信號,由OS按該頁在磁盤上的位置,把該頁信息從磁盤讀出裝入主存后再重新執行這條指令。
(2)設計“地址轉換”程序模擬硬件的地址轉換工作。
當訪問的頁在主存時,則形成絕對地址,但不去模擬指令的執行,而用輸出轉換后的地址來代替一條指令的執行。當訪問的頁不在主存時,則輸出“*該頁頁號”,表示產生了一次缺頁中斷,執行缺頁中斷程序。該模擬程序的算法如下圖所示。
地址轉換模擬流程圖
(3) 缺頁中斷模擬。
在頁式虛擬存儲系統中,當硬件發出缺頁中斷請求后,引起操作系統來處理這個中斷事件。如果主存有空閑物理塊,則調入該頁并修改頁表;如果主存中沒有空閑物理塊,則可用FIFO頁面置換算法或者LRU頁面置換算法從該作業中在主存的頁面中選一頁淘汰,被淘汰的頁是否需要重新寫回磁盤,由修改標志決定。然后再把當前要訪問的頁裝入該塊。調出和裝入后都要修改頁表中的相應信息。
四、數據結構、模塊劃分
(1)存放頁表的結構體
struct info //頁表信息結構體
{
int pageno;
int flag; //頁標志,1表示該頁已在主存,0表示該頁不在主存
int block; //塊號
char disk[10]; //在磁盤上的位置
int dirty; //更新標志(修改標志)
}pagelist[SizeOfPage];
(2)存放操作數、邏輯地址以及頁表信息的結構體
struct work{
char operands[10];
long adress;
int pagenum; //頁號
int page_local;//頁內地址
int sign; //標志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號
int page_back;
}worklist[12];
(3)使用數組進行模擬分配的三個物理塊,po始終指向最先進去的頁號,模擬FIFO算法
long po=0; //隊列標記
long P[M]={0,1,2}; //假設內存中最多允許M=3個頁面
(4)使用文本文件進行內存空間初始化
存放操作數文本文件:
存放頁表信息文本文件:
void init_ex1() //內存空間初始化。
{
FILE *fp = fopen(“page.txt”,“r”), *fq = fopen(“task.txt”,“r”);
int i = 0;
int a = 0, b = 0, c=0, d=0;
char e[10];
while(fscanf(fp,"%d%d%d%d%s",&a,&b,&c,&d,&e)!=EOF)
{
pagelist[i].pageno=a;
pagelist[i].flag=b;
pagelist[i].block=c;
pagelist[i].dirty=d;
strcpy(pagelist[i].disk, e);
i++;
}
char s[10];
long n = 0;
int k=0;
while(fscanf(fq,"%s%ld",&s,&n)!=EOF)
{
if(k >= 12)
break;
strcpy(worklist[k].operands, s);
worklist[k].adress=n;
k++;
}
}
(5)輸出函數
void print()
{
/* char operands[10];
long adress;
int pagenum; //頁號
int page_local;//頁內地址
int sign; //標志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號
int page_back; //是否寫回
*/
printf(“以下數據1表示是,0表示否\n”);
printf(“操作數\t邏輯地址\t頁號\t頁內地址\t是否命中\t物理塊號\t物理地址\t淘汰頁號\t是否寫回\n”);
for(int i=0;i<12;i++)
{
printf("%s\t%ld\t\t%d\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d",worklist[i].operands,worklist[i].adress,worklist[i].pagenum,worklist[i].page_local,worklist[i].sign,worklist[i].Block,worklist[i].page_adress,worklist[i].page_out,worklist[i].page_back);
printf("\n");
}
}
(6)模擬FIFO頁面調度算法
void work_FIFO()
{
int i,j;
for(i=0;i<12;i++)
{
worklist[i].pagenum=worklist[i].adress / 128;
worklist[i].page_local=worklist[i].adress % 128;
worklist[i].page_back = 0;
}
(7)主函數
int main()
{
init_ex1();
work_FIFO();
print();
return 0;
}
五、畫出程序的基本結構框圖和流程圖(包括主程序流程圖、模塊詳細設計流程圖等),對程序的每一部分要有詳細的設計分析說明,說明設計實現所用的原理。
main()函數
init_ex1()函數
使用文本文件進行內存初始化工作
(1)在程序所在目錄下創建兩個文本文件page.txt和task.txt
(2)讀取文件內容,用循環將文件內容賦值給頁表結構體的成員(pagelist)和存放操作數等結構體的成員(worklist)
work_FIFO()
使用雙重循環
(1)邏輯地址進行計算頁號和頁內地址
(2)進行條件判斷,如果頁號標志位1,即在主存中,進行物理地址轉換,否則進行缺頁中斷處理,使用P[M]數組模擬三個分配的物理塊,po始終指向最先進去的頁號
六、源代碼,要求格式規范,適當加注釋,以有助于說明問題為宜,注釋不少于三分之一。
#include<stdio.h>
#include
#define SizeOfPage 7
#define SizeOfBlock 128
#define M 3
struct info //頁表信息結構體
{
int pageno;
int flag; //頁標志,1表示該頁已在主存,0表示該頁不在主存
int block; //塊號
char disk[10]; //在磁盤上的位置
int dirty; //更新標志(修改標志)
}pagelist[SizeOfPage];
struct work{
char operands[10];
long adress;
int pagenum; //頁號
int page_local;//頁內地址
int sign; //標志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號
int page_back;
}worklist[12];
long po=0; //隊列標記
long P[M]={0,1,2}; //假設內存中最多允許M=3個頁面
void init_ex1() //內存空間初始化。
{
//memset(pagelist,0,sizeof(pagelist)); 內存空間初始化,第一個值為指定的內存地址,塊的大小由第三個參數指定,這個函數通常為新申請的內存做初始化工作, 其返回值為s。
}
void print()
{
/* char operands[10];
long adress;
int pagenum; //頁號
int page_local;//頁內地址
int sign; //標志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號
int page_back; //是否寫回
*/
printf(“以下數據1表示是,0表示否\n”);
printf(“操作數\t邏輯地址\t頁號\t頁內地址\t是否命中\t物理塊號\t物理地址\t淘汰頁號\t是否寫回\n”);
for(int i=0;i<12;i++)
{
printf("%s\t%ld\t\t%d\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d",worklist[i].operands,worklist[i].adress,worklist[i].pagenum,worklist[i].page_local,worklist[i].sign,worklist[i].Block,worklist[i].page_adress,worklist[i].page_out,worklist[i].page_back);
printf("\n");
}
}
void work_FIFO()
{
}
int main()
{
init_ex1();
work_FIFO();
print();
}
七、運行的結果,要求有對結果的分析
結果分析:
頁號=int(邏輯地址/每塊長度(128)) 頁內地址=邏輯地址%每塊長度(128)
初始內存時,存在主存的頁號有0,1,2號頁。下面進行三個舉例驗證輸出結果是否正確:
①第一個操作數為“+”,邏輯地址為:389,頁號=int(389/128)=3,頁內地址=389%128=5
此時,3號頁不在主存中,未命中(為0),產生缺頁中斷,使用FIFO算法進行頁面調度,淘汰最先進入主存的頁號,即0頁,故0號頁淘汰,將淘汰頁的物理塊賦值給調入頁號的物理塊,極為5,物理地址為:5128+5=645,操作數不為“存”,不寫回外存。
②第二個操作數為“+”,邏輯地址為:150,頁號=int(150/128)=1,頁內地址=150%128=22
此時,在主存是頁號有3,1,2,故命中(為1),物理塊號為8,物理地址為:8128+22=1046,命中,無淘汰頁號,即記為-1,操作數不為“存”,不寫回外存。
③第四個操作數為“存”,邏輯地址為:78,頁號=int(78/128)=0,頁內地址=78%128=78
此時,在主存中的頁號有1,2,3,未命中,產生缺頁中斷,根據FIFO算法,淘汰1號頁,調入0號頁,物理塊號為8,物理地址為:8*128+78=1102,操作數為“存”,寫回外存,記為1。以此類推,現不再重復驗證。
八、主要參考資料
[1] 湯子瀛等. 計算機操作系統(第三版). 西安:西安電子科技大學出版社2007
[2] [美]William Stallings. 操作系統――內核與設計原理. 北京:電子工業出版社 2001
[3] [美]Abraham Silberschatz等. 操作系統概念(第六版) 北京:高等教育出版社 2004
[4] [荷]Andrews Tanenbaum. 現代操作系統(第2版)北京:機械工業出版社 2005
[5] 譚浩強. C程序設計(第四版). 北京:清華大學出版社2010
總結
以上是生活随笔為你收集整理的C语言模拟实现虚拟存储管理(请求分页存储管理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【译】网页像素追踪原理
- 下一篇: 会员等级图标js脚本