日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言模拟实现虚拟存储管理(请求分页存储管理)

發(fā)布時(shí)間:2023/12/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言模拟实现虚拟存储管理(请求分页存储管理) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C語言模擬實(shí)現(xiàn)虛擬存儲(chǔ)管理(請(qǐng)求分頁存儲(chǔ)管理)使用FIFO算法
1)實(shí)驗(yàn)?zāi)康?br /> 2)實(shí)驗(yàn)內(nèi)容
3)實(shí)驗(yàn)基本原理和解決方案
4)數(shù)據(jù)結(jié)構(gòu)、模塊劃分
5)畫出程序的基本結(jié)構(gòu)框圖和流程圖(包括主程序流程圖、模塊詳細(xì)設(shè)計(jì)流程圖等),對(duì)程序的每一部分要有詳細(xì)的設(shè)計(jì)分析說明,說明設(shè)計(jì)實(shí)現(xiàn)所用的原理。
6)源代碼,要求格式規(guī)范,適當(dāng)加注釋,以有助于說明問題為宜,注釋不少于三分之一。
7)運(yùn)行的結(jié)果,要求有對(duì)結(jié)果的分析
8)參考資料
一、實(shí)驗(yàn)?zāi)康?br /> 存儲(chǔ)管理的主要功能之一是合理的分配空間。請(qǐng)求分頁存儲(chǔ)管理是一種常用的虛擬存儲(chǔ)管理技術(shù)。本實(shí)驗(yàn)的目的是:通過編程模擬實(shí)現(xiàn)請(qǐng)求分頁存儲(chǔ)管理中硬件地址轉(zhuǎn)換過程、缺頁中斷處理過程,以及先進(jìn)先出頁面置換算法,加深對(duì)頁式虛擬存儲(chǔ)管理的理解,了解虛擬存儲(chǔ)技術(shù)的特點(diǎn),掌握請(qǐng)求頁式存儲(chǔ)管理的頁面置換方法;通過編寫和調(diào)試地址轉(zhuǎn)換過程的模擬程序以加強(qiáng)對(duì)地址轉(zhuǎn)換過程的了解。

二、實(shí)驗(yàn)內(nèi)容
閱讀教材《計(jì)算機(jī)操作系統(tǒng)》第四章,掌握存儲(chǔ)器管理相關(guān)概念和原理。
(1)用C語言實(shí)現(xiàn)對(duì)分頁式存儲(chǔ)管理中的硬件的地址轉(zhuǎn)換和產(chǎn)生缺頁中斷。
(2)設(shè)計(jì)頁表。
頁式虛擬存儲(chǔ)系統(tǒng)是把作業(yè)的副本存放在磁盤上,當(dāng)作業(yè)被選中時(shí),可把作業(yè)的開始幾頁先裝入主存且啟動(dòng)執(zhí)行。為此,在為作業(yè)建立頁表時(shí),應(yīng)說明哪些頁已在主存,哪些頁尚未裝入主存,頁表的格式為:
頁 號(hào) 標(biāo)志 主存塊號(hào) 修改標(biāo)志 在磁盤上的位置

其中:
標(biāo)志——用來表示對(duì)應(yīng)頁是否已經(jīng)裝入主存,標(biāo)志位=1,則表示該頁已經(jīng)在主存中,標(biāo)志位=0,則表示該頁尚未裝入主存。
主存塊號(hào)——用來表示已經(jīng)裝入主存的頁所占的物理塊號(hào)。
修改標(biāo)志——用來表示已經(jīng)裝入主存的頁是否被修改過。為,則表示該頁裝入主存后被修改過;為0,則表示該頁該頁裝入主存后未被修改過。
在磁盤上的位置——用來指出作業(yè)副本的每一頁被存放在磁盤上的位置。
可根據(jù)頁面置換算法的不同,頁表的內(nèi)容可以作適當(dāng)?shù)脑鰟h。

三、實(shí)驗(yàn)基本原理和解決方案
(1)地址計(jì)算。
作業(yè)執(zhí)行時(shí),先根據(jù)指令中的邏輯地址算出參加運(yùn)算的操作數(shù)存放的頁號(hào)和頁內(nèi)地址,硬件的地址轉(zhuǎn)換機(jī)構(gòu)按頁號(hào)查頁表,若該頁對(duì)應(yīng)標(biāo)志為“1”,則表示該頁已在主存,根據(jù)關(guān)系式:
絕對(duì)地址=塊號(hào)*塊長+頁內(nèi)地址
計(jì)算出欲訪問的主存單元地址。按計(jì)算出的絕對(duì)地址可以取到操作數(shù),完成一條指令的執(zhí)行。若訪問的頁標(biāo)志為“0”,則表示該頁不在主存,這時(shí)硬件發(fā)“缺頁中斷”信號(hào),由OS按該頁在磁盤上的位置,把該頁信息從磁盤讀出裝入主存后再重新執(zhí)行這條指令。
(2)設(shè)計(jì)“地址轉(zhuǎn)換”程序模擬硬件的地址轉(zhuǎn)換工作。
當(dāng)訪問的頁在主存時(shí),則形成絕對(duì)地址,但不去模擬指令的執(zhí)行,而用輸出轉(zhuǎn)換后的地址來代替一條指令的執(zhí)行。當(dāng)訪問的頁不在主存時(shí),則輸出“*該頁頁號(hào)”,表示產(chǎn)生了一次缺頁中斷,執(zhí)行缺頁中斷程序。該模擬程序的算法如下圖所示。

地址轉(zhuǎn)換模擬流程圖
(3) 缺頁中斷模擬。
在頁式虛擬存儲(chǔ)系統(tǒng)中,當(dāng)硬件發(fā)出缺頁中斷請(qǐng)求后,引起操作系統(tǒng)來處理這個(gè)中斷事件。如果主存有空閑物理塊,則調(diào)入該頁并修改頁表;如果主存中沒有空閑物理塊,則可用FIFO頁面置換算法或者LRU頁面置換算法從該作業(yè)中在主存的頁面中選一頁淘汰,被淘汰的頁是否需要重新寫回磁盤,由修改標(biāo)志決定。然后再把當(dāng)前要訪問的頁裝入該塊。調(diào)出和裝入后都要修改頁表中的相應(yīng)信息。
四、數(shù)據(jù)結(jié)構(gòu)、模塊劃分
(1)存放頁表的結(jié)構(gòu)體
struct info //頁表信息結(jié)構(gòu)體
{
int pageno;
int flag; //頁標(biāo)志,1表示該頁已在主存,0表示該頁不在主存
int block; //塊號(hào)
char disk[10]; //在磁盤上的位置
int dirty; //更新標(biāo)志(修改標(biāo)志)

}pagelist[SizeOfPage];
(2)存放操作數(shù)、邏輯地址以及頁表信息的結(jié)構(gòu)體
struct work{
char operands[10];
long adress;
int pagenum; //頁號(hào)
int page_local;//頁內(nèi)地址
int sign; //標(biāo)志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號(hào)
int page_back;

}worklist[12];

(3)使用數(shù)組進(jìn)行模擬分配的三個(gè)物理塊,po始終指向最先進(jìn)去的頁號(hào),模擬FIFO算法
long po=0; //隊(duì)列標(biāo)記
long P[M]={0,1,2}; //假設(shè)內(nèi)存中最多允許M=3個(gè)頁面
(4)使用文本文件進(jìn)行內(nèi)存空間初始化
存放操作數(shù)文本文件:

存放頁表信息文本文件:

void init_ex1() //內(nèi)存空間初始化。
{
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++;
}

fclose(fp); fclose(fq);

}
(5)輸出函數(shù)
void print()
{
/* char operands[10];
long adress;
int pagenum; //頁號(hào)
int page_local;//頁內(nèi)地址
int sign; //標(biāo)志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號(hào)
int page_back; //是否寫回
*/
printf(“以下數(shù)據(jù)1表示是,0表示否\n”);
printf(“操作數(shù)\t邏輯地址\t頁號(hào)\t頁內(nèi)地址\t是否命中\(zhòng)t物理塊號(hào)\t物理地址\t淘汰頁號(hào)\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頁面調(diào)度算法
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;

for(j=0;j<7;j++){if(pagelist[j].pageno == worklist[i].pagenum){if(pagelist[j].flag==1){worklist[i].Block = pagelist[pagelist[j].pageno].block;worklist[i].sign=1;worklist[i].page_adress=(pagelist[pagelist[j].pageno].block* SizeOfBlock + worklist[i].page_local);//worklist[i].Blockworklist[i].page_out=-1;if(!(strcmp(worklist[i].operands,"存"))){pagelist[worklist[i].pagenum].dirty = 1; //是否寫回磁盤,修改頁表worklist[i].page_back = 1;}}else{//printf("*%d\n",worklist[i].pagenum);pagelist[P[po]].flag=0; //將flag標(biāo)志位置0,表示當(dāng)前頁面已被置換出去worklist[i].page_out=P[po];worklist[i].Block=pagelist[P[po]].block;pagelist[j].block=pagelist[P[po]].block;worklist[i].page_adress=(worklist[i].Block*SizeOfBlock+worklist[i].page_local);pagelist[j].flag=1;worklist[i].sign=0;P[po]=pagelist[j].pageno; //保存當(dāng)前頁面所在的位置po=(po+1)%M; if(!(strcmp(worklist[i].operands,"存"))){pagelist[worklist[i].pagenum].dirty = 1; //是否寫回磁盤,修改頁表worklist[i].page_back = 1;}}}else{continue;}}}

}
(7)主函數(shù)
int main()
{
init_ex1();
work_FIFO();
print();
return 0;
}
五、畫出程序的基本結(jié)構(gòu)框圖和流程圖(包括主程序流程圖、模塊詳細(xì)設(shè)計(jì)流程圖等),對(duì)程序的每一部分要有詳細(xì)的設(shè)計(jì)分析說明,說明設(shè)計(jì)實(shí)現(xiàn)所用的原理。
main()函數(shù)

init_ex1()函數(shù)

使用文本文件進(jìn)行內(nèi)存初始化工作
(1)在程序所在目錄下創(chuàng)建兩個(gè)文本文件page.txt和task.txt
(2)讀取文件內(nèi)容,用循環(huán)將文件內(nèi)容賦值給頁表結(jié)構(gòu)體的成員(pagelist)和存放操作數(shù)等結(jié)構(gòu)體的成員(worklist)
work_FIFO()

使用雙重循環(huán)
(1)邏輯地址進(jìn)行計(jì)算頁號(hào)和頁內(nèi)地址
(2)進(jìn)行條件判斷,如果頁號(hào)標(biāo)志位1,即在主存中,進(jìn)行物理地址轉(zhuǎn)換,否則進(jìn)行缺頁中斷處理,使用P[M]數(shù)組模擬三個(gè)分配的物理塊,po始終指向最先進(jìn)去的頁號(hào)

六、源代碼,要求格式規(guī)范,適當(dāng)加注釋,以有助于說明問題為宜,注釋不少于三分之一。
#include<stdio.h>
#include
#define SizeOfPage 7
#define SizeOfBlock 128
#define M 3
struct info //頁表信息結(jié)構(gòu)體
{
int pageno;
int flag; //頁標(biāo)志,1表示該頁已在主存,0表示該頁不在主存
int block; //塊號(hào)
char disk[10]; //在磁盤上的位置
int dirty; //更新標(biāo)志(修改標(biāo)志)

}pagelist[SizeOfPage];

struct work{
char operands[10];
long adress;
int pagenum; //頁號(hào)
int page_local;//頁內(nèi)地址
int sign; //標(biāo)志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號(hào)
int page_back;

}worklist[12];

long po=0; //隊(duì)列標(biāo)記
long P[M]={0,1,2}; //假設(shè)內(nèi)存中最多允許M=3個(gè)頁面

void init_ex1() //內(nèi)存空間初始化。
{
//memset(pagelist,0,sizeof(pagelist)); 內(nèi)存空間初始化,第一個(gè)值為指定的內(nèi)存地址,塊的大小由第三個(gè)參數(shù)指定,這個(gè)函數(shù)通常為新申請(qǐng)的內(nèi)存做初始化工作, 其返回值為s。

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++; }fclose(fp); fclose(fq);

}

void print()
{
/* char operands[10];
long adress;
int pagenum; //頁號(hào)
int page_local;//頁內(nèi)地址
int sign; //標(biāo)志
int Block;
int page_adress;//物理地址
int page_out; //淘汰頁號(hào)
int page_back; //是否寫回
*/
printf(“以下數(shù)據(jù)1表示是,0表示否\n”);
printf(“操作數(shù)\t邏輯地址\t頁號(hào)\t頁內(nèi)地址\t是否命中\(zhòng)t物理塊號(hào)\t物理地址\t淘汰頁號(hào)\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 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;for(j=0;j<7;j++){if(pagelist[j].pageno == worklist[i].pagenum){if(pagelist[j].flag==1){worklist[i].Block = pagelist[pagelist[j].pageno].block;worklist[i].sign=1;//printf("物理塊:%d\n",worklist[i].Block);worklist[i].page_adress=(pagelist[pagelist[j].pageno].block* SizeOfBlock + worklist[i].page_local);//worklist[i].Block// printf("物理地址:%d\n",worklist[i].page_adress);worklist[i].page_out=-1;if(!(strcmp(worklist[i].operands,"存"))){pagelist[worklist[i].pagenum].dirty = 1; //是否寫回磁盤,修改頁表worklist[i].page_back = 1;}}else{//printf("*%d\n",worklist[i].pagenum);pagelist[P[po]].flag=0; //將flag標(biāo)志位置0,表示當(dāng)前頁面已被置換出去worklist[i].page_out=P[po];worklist[i].Block=pagelist[P[po]].block;pagelist[j].block=pagelist[P[po]].block;worklist[i].page_adress=(worklist[i].Block*SizeOfBlock+worklist[i].page_local);pagelist[j].flag=1;worklist[i].sign=0;P[po]=pagelist[j].pageno; //保存當(dāng)前頁面所在的位置po=(po+1)%M; if(!(strcmp(worklist[i].operands,"存"))){pagelist[worklist[i].pagenum].dirty = 1; //是否寫回磁盤,修改頁表worklist[i].page_back = 1;}}}else{continue;}}}

}

int main()
{
init_ex1();
work_FIFO();
print();

return 0;

}
七、運(yùn)行的結(jié)果,要求有對(duì)結(jié)果的分析
結(jié)果分析:
頁號(hào)=int(邏輯地址/每塊長度(128)) 頁內(nèi)地址=邏輯地址%每塊長度(128)
初始內(nèi)存時(shí),存在主存的頁號(hào)有0,1,2號(hào)頁。下面進(jìn)行三個(gè)舉例驗(yàn)證輸出結(jié)果是否正確:
①第一個(gè)操作數(shù)為“+”,邏輯地址為:389,頁號(hào)=int(389/128)=3,頁內(nèi)地址=389%128=5
此時(shí),3號(hào)頁不在主存中,未命中(為0),產(chǎn)生缺頁中斷,使用FIFO算法進(jìn)行頁面調(diào)度,淘汰最先進(jìn)入主存的頁號(hào),即0頁,故0號(hào)頁淘汰,將淘汰頁的物理塊賦值給調(diào)入頁號(hào)的物理塊,極為5,物理地址為:5128+5=645,操作數(shù)不為“存”,不寫回外存。
②第二個(gè)操作數(shù)為“+”,邏輯地址為:150,頁號(hào)=int(150/128)=1,頁內(nèi)地址=150%128=22
此時(shí),在主存是頁號(hào)有3,1,2,故命中(為1),物理塊號(hào)為8,物理地址為:8128+22=1046,命中,無淘汰頁號(hào),即記為-1,操作數(shù)不為“存”,不寫回外存。
③第四個(gè)操作數(shù)為“存”,邏輯地址為:78,頁號(hào)=int(78/128)=0,頁內(nèi)地址=78%128=78
此時(shí),在主存中的頁號(hào)有1,2,3,未命中,產(chǎn)生缺頁中斷,根據(jù)FIFO算法,淘汰1號(hào)頁,調(diào)入0號(hào)頁,物理塊號(hào)為8,物理地址為:8*128+78=1102,操作數(shù)為“存”,寫回外存,記為1。以此類推,現(xiàn)不再重復(fù)驗(yàn)證。
八、主要參考資料
[1] 湯子瀛等. 計(jì)算機(jī)操作系統(tǒng)(第三版). 西安:西安電子科技大學(xué)出版社2007
[2] [美]William Stallings. 操作系統(tǒng)――內(nèi)核與設(shè)計(jì)原理. 北京:電子工業(yè)出版社 2001
[3] [美]Abraham Silberschatz等. 操作系統(tǒng)概念(第六版) 北京:高等教育出版社 2004
[4] [荷]Andrews Tanenbaum. 現(xiàn)代操作系統(tǒng)(第2版)北京:機(jī)械工業(yè)出版社 2005
[5] 譚浩強(qiáng). C程序設(shè)計(jì)(第四版). 北京:清華大學(xué)出版社2010

總結(jié)

以上是生活随笔為你收集整理的C语言模拟实现虚拟存储管理(请求分页存储管理)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。