C语言页式虚存管理

peter-hill 2017-11-20 10:28:26

实验二 页式虚存管理
1.实验内容:模拟请求页式存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断;
2.要求:
① 指令序列的设定可以执行拟定,格式如表3;
② 在完成了FIFO换页策略后,可以选做LRU的换页策略,并进行比较;
③ 作业允许的页架数m在不同情况下的缺页中断率;
④ 程序运行时显示地址转变和页面调入调出过程。
3.步骤:
① 设计页表及其数据结构:
页号
标志:是否在主存;
页架号:设定页表在主存的位置;
修改标志:设定页面在主存中是否修改过;
磁盘上位置:设定页面在辅存中的位置;
例如:装入新页置换旧页时,若旧页在执行中没有被修改过,则不必将该页重写磁盘。因此,页表中增加是否修改过的标志,执行“存”指令和“写”指令时将对应的修改标志置成“1”表示修改过,否则为“0”表示未修改过。
表 1 页表格式
页号 标志 页架号 修改标志 在磁盘上位置





②设计一个地址转换程序半模拟硬件的地址转换和缺页中断。
当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可以输出转换后的绝对地址来表示一条指令已执行完成。当访问的页不在主存中时,则输出“*页号”来表示硬件产生了一次缺页中断。模拟地址转换流程见图1.1。
③ 设计FIFO页面调度程序;
FIFO页面调度算法总是先调出作业中最先进入主存中的哪一页。因此可以用一个数组来表示(或构成)页号队列。数据中每个元素是该作业已在主存中的页面号,假定分配给作业的页(架)数为m,且该作业开始的m页已装入主存,则数组可由m个元素构成。
P[0],P[1],P[2],…,P[m-1]
它们的初值为P[0]:=0,P[1]:=1,P[2]:=2,…,P[m-1]:=m-1
用一指针K指示当要调入新页时应调出的页在数组中的位置,K的初值为“0”,当产生缺页中断后,操作系统总是选择P[K]所指出的页面调出,然后执行。
④ 设计输入数据和输出格式;
如: 假定主存中页架大小为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4个页架,且该作业的第0页至第3页已装入内存,其作3页未主存,该作业的页表如下:

页号 标志 页架号 修改标志 在磁盘上位置
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所示:
操作 页号 页内地址 操作 页号 页内地址
+ 0 070 移位 4 053
- 1 050 + 5 023
× 2 015 存 1 037
存 3 021 取 2 078
取 0 056 + 4 001
- 6 040 存 6 084
依次执行上述指令调试你所设计的程序(仅模拟指令的执行,不考虑序列中具体操作的执行)。
⑤ 编程上机,验证结果。
4.实验报告:
为进一步考察程序的执行,可自行确定若干组指令,运行程序,核对执行结果实验报告:
① 实验题目;
② 程序中所用的数据结构及说明;
③ 打印一份源程序并附上必要的说明;
④ 按照指令的执行序列,打印输出结果:绝对地址或调出、调入的页号。
P[K]:=要装入的新页页号
K:=(k+1)mod m
在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入过程,模拟程序的流程图见附图1.1。

按流程控制过程如下:
提示:输入指令的页号和页内偏移和是否存指令 ,若d为-1则结束,否则进入流程控制过程,得P1和d,查表在主存时绝对地址P1×1024+d







...全文
272 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
destory27 2017-11-20
  • 打赏
  • 举报
回复
#ifndef _PAGEM_H #define _PAGEM_H #include "FIFO.h" //enum EXISTS{NON_EXIST, EXIST}; //enum Update{Update_N, Update_Y}; typedef struct PMT{ unsigned char PageID; //页号 unsigned char F_EXISTS; //是否在主存 unsigned char PframeID; //页框号 unsigned char F_Update; //是否修改过 unsigned char DiskPosition; //磁盘位置 struct PMT *NEXT; //保存下一页面地址 }pmt; //指令 typedef struct AccQueue{ unsigned char PageID; //页号 unsigned int offset; //页内偏移量 unsigned char F_Instruction; //是否存指令 1:存 0:不存 -1:退出 struct AccQueue *next; unsigned char AccInfo[3]; //用于输出 unsigned char F_interrupt; //页面中断 }AccQue; typedef struct{ node *front; node *rear; }FIFO; pmt* SetPMT(void); void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque); void PMTInfo(pmt ** P_page); FIFO* SetFIFO(pmt ** P_page); void Callingorder(pmt **P_page, FIFO **fifo, pmt **page); void Performance(AccQue **accque); #endif #include <stdio.h> #include <malloc.h> #include <stdio.h> #include <string.h> #include "PageM.h" const unsigned char M = 3; //主存容量 const unsigned char PageNum = 7; //该作业页面数 const unsigned int Msize = 1024; // pmt* SetPMT(void) { pmt *P_page = (pmt *)malloc(sizeof(pmt)); (pmt *)memset(P_page, 0x00, sizeof(pmt)); P_page->NEXT = NULL; for(int i = 0; i < PageNum; ++i) { pmt *P_npage = (pmt *)malloc(sizeof(pmt)); //建立页面 (pmt *)memset(P_npage, 0x00, sizeof(pmt)); P_npage->NEXT = NULL; P_npage->PageID = i; if(i < M) { P_npage->F_EXISTS = 1; P_npage->PframeID = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) - 0X9; } else { P_npage->F_EXISTS = 0; P_npage->PframeID = -1; } P_npage->F_Update = 0; P_npage->DiskPosition = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) + ((i << 1) | 0xA); pmt *page = P_page; while(page->NEXT) page = page->NEXT; page->NEXT = P_npage; page = NULL; } return P_page; } //访问 void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque) { if(!P_page && !*P_page) fprintf(stderr, "P_page Error!\n"); if(!fifo && !*fifo) fprintf(stderr, "fifo Error!\n"); if(!structaccque && !*structaccque) fprintf(stderr, "structaccque Error!\n"); if(!accque && !*accque) fprintf(stderr, "accque Error!\n"); //遍历PMT表,查看访问页面是否在PMT表中 pmt *pagetmp = (*P_page)->NEXT; unsigned char Pflag = 0; //页面不在 while(pagetmp) { if(pagetmp->PageID == (*structaccque)->PageID) { Pflag = 1; //存指令 if(1 == (*structaccque)->F_Instruction) //是否更新 pagetmp->F_Update = 1; break; } pagetmp = pagetmp->NEXT; } if(!Pflag) { fprintf(stderr, "\t==>>没有该页面.\n"); return ; } //访问顺序保存到AccQue; /*AccQue *accque = (AccQue *)malloc(sizeof(AccQue)); //连接有效访问信息 (AccQue *)memset(accque, 0x00, sizeof(AccQue));*/ AccQue *acctmp = (*accque); while(acctmp->next) acctmp = acctmp->next; acctmp->next = (*structaccque); //将主存中的信息装入数组 node *Pageid = (*fifo)->front; unsigned char i = 0; while(Pageid != (*fifo)->rear->next) { (*accque)->AccInfo[i++] = Pageid->PageID; Pageid = Pageid->next; } if(i < 2) for(i; i <= 2; (*accque)->AccInfo[i++] = -1) ; //遍历队列 没有:需要调入 有:刷新 node *fifotmp = (*fifo)->front; unsigned char Fflag = 0; //不在队列中 while(fifotmp != (*fifo)->rear->next) { if(fifotmp->PageID == (*structaccque)->PageID) { Fflag = 1; (*structaccque)->F_interrupt = 0; //在队列 unsigned char i = 0; node *Pageidt = (*fifo)->front; while(Pageidt != (*fifo)->rear->next) { (*structaccque)->AccInfo[i++] = Pageidt->PageID; Pageidt = Pageidt->next; } if(i < 2) for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) ; break; } fifotmp = fifotmp->next; } if(!Fflag) //调入 { (*structaccque)->F_interrupt = 1; Callingorder(P_page, fifo, &pagetmp); node *Pageidtmp = (*fifo)->front; unsigned char i = 0; while(Pageidtmp != (*fifo)->rear->next) { (*structaccque)->AccInfo[i++] = Pageidtmp->PageID; Pageidtmp = Pageidtmp->next; } if(i < 2) for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) ; } else if(1 == Fflag) { fprintf(stderr, "\t==>>页面[%d]在主存中.", (*structaccque)->PageID); fprintf(stderr, "\t==>>地址: %d \n.", (*structaccque)->PageID * Msize + (*structaccque)->offset); } return; } void PMTInfo(pmt ** P_page) { if(!P_page || !*P_page) fprintf(stderr, "Error!"); fprintf(stderr, "\t+--------------------------------------------------------+\n"); fprintf(stderr, "\t| 页号 | 标志 | 页框号 | 修改标志 | 在磁盘位置 |\n"); fprintf(stderr, "\t+--------------------------------------------------------+\n"); pmt *pagetmp = *P_page; while(pagetmp->NEXT) { pmt *page = pagetmp->NEXT; fprintf(stderr, "\t| %d | %d |", page->PageID, page->F_EXISTS); if(255 == page->PframeID) fprintf(stderr, " "); else fprintf(stderr, " %2d ", page->PframeID); fprintf(stderr, "| %d | %2X |\n", page->F_Update, page->DiskPosition); //fprintf(stderr, "\t|--------------------------------------------------------|\n"); pagetmp = pagetmp->NEXT; // page = NULL; } fprintf(stderr, "\t+--------------------------------------------------------+\n"); return ; } #ifndef _FIFO_H #define _FIFO_H #include "PageM.h" typedef struct Node{ unsigned char PageID; //页号 struct Node *next; }node; #endif #include <stdio.h> #include <malloc.h> #include <string.h> #include "PageM.h" #include "FIFO.h" extern const unsigned char M; FIFO* SetFIFO(pmt ** P_page) { if(!P_page || !*P_page) fprintf(stderr, "Error!"); FIFO *fifo = (FIFO *)malloc(sizeof(FIFO)); (FIFO*)memset(fifo, 0x00, sizeof(FIFO)); fifo->front = (node *)malloc(sizeof(node)); (node *)memset(fifo->front, 0x00, sizeof(node)); fifo->front->next = NULL; fifo->rear = (node *)malloc(sizeof(node)); (node *)memset(fifo->rear, 0x00, sizeof(node)); fifo->rear = fifo->front; pmt *page = (*P_page)->NEXT; int capacity = 0; while(page && capacity++ < M) { node *P_node = (node *)malloc(sizeof(node)); (node *)memset(P_node, 0x00, sizeof(node)); P_node->PageID = page->PageID; P_node ->next = NULL; if(1 == capacity) fifo->front = P_node; fifo->rear->next = P_node; fifo->rear = P_node; page = page->NEXT; } return fifo; } //调入指令 void Callingorder(pmt **P_page, FIFO **fifo, pmt **page) { if(!page && !*page) fprintf(stderr, "Error!"); if(!fifo && !*fifo) fprintf(stderr, "Error!"); // 调出处理 pmt *pagetmp = (*P_page); while(pagetmp->NEXT) { if(pagetmp->NEXT->PageID == (*fifo)->front->PageID) { pagetmp->NEXT->F_EXISTS = 0; //设置不在主存 if(1 == pagetmp->NEXT->F_Update) { fprintf(stderr, "\t==>>页面[%d]的内容写回磁盘。\n", pagetmp->NEXT->PageID); pagetmp->NEXT->F_Update = 0; } //pagetmp->NEXT->PframeID = -1; fprintf(stderr, "\t==>>页面[%d]调出.\n", pagetmp->NEXT->PageID); break; } pagetmp = pagetmp->NEXT; } node *temp = (*fifo)->front; //队首 (*fifo)->front = (*fifo)->front->next; free(temp); node *P_node = (node *)malloc(sizeof(node)); (node *)memset(P_node, 0x00, sizeof(node)); P_node->PageID = (*page)->PageID; unsigned char i = (*page)->PageID; (*page)->PframeID = pagetmp->NEXT->PframeID; pagetmp->NEXT->PframeID = -1; (*page)->F_EXISTS = 1; P_node->next = NULL; (*fifo)->rear->next = P_node; (*fifo)->rear = P_node; fprintf(stderr, "\t==>>页面[%d]调入.\n", P_node->PageID); return ; } //FIFO性能分析 void Performance(AccQue **accque) { AccQue *acctmp = (*accque)->next; if(!acctmp) { fprintf(stderr, "\t==>>访问队列为空.\n"); return ; } fprintf(stderr, "\t+--------------------------------------------------------+\n"); fprintf(stderr, "\t| 时刻 |"); unsigned char time = 1; while(acctmp) { fprintf(stderr, " %d |", time++); acctmp = acctmp->next; } fprintf(stderr, "\n"); acctmp = (*accque)->next; fprintf(stderr, "\t| 页面走向 |"); while(acctmp) { fprintf(stderr, " %d |", acctmp->PageID); acctmp = acctmp->next; } fprintf(stderr, "\n"); acctmp = (*accque)->next; fprintf(stderr, "\t| |"); while(acctmp) { fprintf(stderr, " %d |", acctmp->AccInfo[2]); acctmp = acctmp->next; } fprintf(stderr, "\n"); fprintf(stderr, "\t| 主存容量 |"); acctmp = (*accque)->next; while(acctmp) { fprintf(stderr, " %d |", acctmp->AccInfo[1]); acctmp = acctmp->next; } fprintf(stderr, "\n"); fprintf(stderr, "\t| |"); acctmp = (*accque)->next; while(acctmp) { fprintf(stderr, " %d |", acctmp->AccInfo[0]); acctmp = acctmp->next; } fprintf(stderr, "\n"); unsigned char tmp = 0; fprintf(stderr, "\t| 缺页中断 |"); acctmp = (*accque)->next; while(acctmp) { fprintf(stderr, " %d |", acctmp->F_interrupt); acctmp = acctmp->next; } fprintf(stderr, "\n"); fprintf(stderr, "\t+--------------------------------------------------------+\n"); int rate = 0; acctmp = (*accque)->next; while(acctmp) { if(1 == acctmp->F_interrupt) ++rate; acctmp = acctmp->next; } fprintf(stderr, "\t 缺页率: %d / %d = %.2lf\n", rate , time-1, ((float)rate/(time-1))); return ; }
完整虚拟存储管理器实验报告!一、实验目的请求页式虚存管理是常用的虚拟存储管理方案之一。通过请求页式虚存管理中对页面置换算法的模拟,有助于理解虚拟存储技术的特点,并加深对请求页式虚存管理的页面调度算法的理解。二、实验环境 Turbo C 2.0/3.0或VC++6.0三、实验内容本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO和LRU算法进行页面置换的情形。其中虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率。程序应允许通过为该进程分配不同的实页数,来比较两种置换算法的稳定性。四、实验说明 1.设计中虚页和实页的表示本设计利用C语言的结构体来描述虚页和实页的结构。pnpfntimepnpfnnext 虚页结构 实页结构在虚页结构中,pn代表虚页号,因为共10个虚页,所以pn的取值范围是0—9。pfn代表实页号,当一虚页未装入实页时,此项值为-1;当该虚页已装入某一实页时,此项值为所装入的实页的实页号pfn。time项在FIFO算法中不使用,在LRU中用来存放对该虚页的最近访问时间。在实页结构中,pn代表虚页号,表示pn所代表的虚页目前正放在此实页中。pfn代表实页号,取值范围(0—n-1)由动态指派的实页数n所决定。next是一个指向实页结构体的指针,用于多个实页以链表形式组织起来,关于实页链表的组织详见下面第4点。2.关于缺页次数的统计为计算命中率,需要统计在20次的虚页访问中命中的次数。为此,程序应设置一个计数器count,来统计虚页命中发生的次数。每当所访问的虚页的pfn项值不为-1,表示此虚页已被装入某实页内,此虚页被命中,count加1。最终命中率=count/20*100%。3.LRU算法中“最近最久未用”页面的确定为了能找到“最近最久未用”的虚页面,程序中可引入一个时间计数器countime,每当要访问一个虚页面时,countime的值加1,然后将所要访问的虚页的time项值设置为增值后的当前countime值,表示该虚页的最后一次被访问时间。当LRU算法需要置换时,从所有已分配实页的虚页中找出time值为最小的虚页就是“最近最久未用”的虚页面,应该将它置换出去。4.算法中实页的组织因为能分配的实页数n是在程序运行时由用户动态指派的,所以应使用链表组织动态产生的多个实页。为了调度算法实现的方便,可以考虑引入free和busy两个链表:free链表用于组织未分配出去的实页,首指针为free_head,初始时n个实页都处于free链表中;busy链表用于组织已分配出去的实页,首指针为busy_head,尾指针为busy_tail,初始值都为null。当所要访问的一个虚页不在实页中时,将产生缺页中断。此时若free链表不为空,就取下链表首指针所指的实页,并分配给该虚页。若free链表为空,则说明n个实页已全部分配出去,此时应进行页面置换:对于FIFO算法要将busy_head 所指的实页从busy链表中取下,分配给该虚页,然后再将该实页插入到busy链表尾部;对于LRU算法则要从所有已分配实页的虚页中找出time值为最小的虚页,将该虚页从装载它的那个实页中置换出去,并在该实页中装入当前正要访问的虚页。~
原创代码+报告(用的是数组)   设计一个请求页式存储管理方案。并编写模拟程序实现之。要求包含:   1.过随机数产生一个指令序列,共320条指令。其地址按下述原则生成:   ①50%的指令是顺序执行的;   ②25%的指令是均匀分布在前地址部分;   ③25%的指令是均匀分布在后地址部分;   #具体的实施方法是:      在[0,319]的指令地址之间随机选区一起点M;      顺序执行一条指令,即执行地址为M+1的指令;      在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;      顺序执行一条指令,其地址为M’+1;      在后地址[M’+2,319]中随机选取一条指令并执行;      重复A—E,直到执行320次指令。   2.指令序列变换成页地址流    设:(1)页面大小为1K;       用户内存容量为4页到32页;        用户虚存容量为32K。   在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:    第0条—第9条指令为第0页(对应虚存地址为[0,9]);    第10条—第19条指令为第1页(对应虚存地址为[10,19]);    。。。。。。。。。。。。。。。。。。。。。    第310条—第319条指令为第31页(对应虚存地址为[310,319]);   按以上方式,用户指令可组成32页。   3. 计算并输出下述各种算法在不同内存容量下的命中率。      FIFO先进先出的算法      LRR最近最少使用算法      OPT最佳淘汰算法(先淘汰最不常用的页地址)      LFR最少访问页面算法      NUR最近最不经常使用算法
管理系统是一种通过计算机技术实现的用于组织、监控和控制各种活动的软件系统。这些系统通常被设计用来提高效率、减少错误、加强安全性,同时提供数据和信息支持。以下是一些常见类型的管理系统: 学校管理系统: 用于学校或教育机构的学生信息、教职员工信息、课程管理、成绩记录、考勤管理等。学校管理系统帮助提高学校的组织效率和信息管理水平。 人力资源管理系统(HRM): 用于处理组织内的人事信息,包括员工招聘、培训记录、薪资管理、绩效评估等。HRM系统有助于企业更有效地管理人力资源,提高员工的工作效率和满意度。 库存管理系统: 用于追踪和管理商品或原材料的库存。这种系统可以帮助企业避免库存过剩或不足的问题,提高供应链的效率。 客户关系管理系统(CRM): 用于管理与客户之间的关系,包括客户信息、沟通记录、销售机会跟踪等。CRM系统有助于企业更好地理解客户需求,提高客户满意度和保留率。 医院管理系统: 用于管理医院或医疗机构的患者信息、医生排班、药品库存等。这种系统可以提高医疗服务的质量和效率。 财务管理系统: 用于记录和管理组织的财务信息,包括会计凭证、财务报表、预算管理等。财务管理系统

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧