操作系统课程设计-模拟设计页式存储管理的分配与回收
操作系统课程设计页式存储

操作系统课程设计报告——页式存储姓名:***班级:J计算机1302学号:**********指导老师:***日期:2016/1/12一、目的和要求1.理解页式存储的基本概念2.通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
3. 3.根据模拟的页式管理设计,掌握在页式存储管理中最基本的两种种页面调度算法FIFO、LRU。
但在两种种算法中均要求在调度程序中产生的页面序列是随机产生的,而不是人为的输入,在执行时只需改变页面的大小及内存容量就可以得到不同的页面序列,另外还需要说明随机的性能和其性能可能对算法的影响,并对随机性要有一定的参数控制能力。
此外,计算并输出FIFO、LRU算法在不同内存容量下的命中率。
具体参数:访问串的长度,访问串,页面个数。
分别用2种不同的方法实现页面的置换,并输出相关信息。
二、基本原理1.页式存储基本原理将各进程的虚拟空间划分成若干个长度相等的页(page),页式管理把内存空间按页的大小划分成片或者页面(page frame),然后把页式虚拟地址与内存地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
页式管理采用请求调页或预调页技术实现了内外存储器的统一管理。
页的划分:2.静态/虚拟分页管理页式管理是一种内存空间存储管理的技术,页式管理分为静态分页管理和虚拟分页管理。
①静态页式存储管理:用户在作业开始执行之前,讲改作业的程序和数据全部装入到主存中,然后,操作系统统通过页表和硬件地址变换实现逻辑地址到屋里地址的转换,从而执行用户程序。
静态分页管理的第一步是为要求内存的作业或进程分配足够的页面。
系统通过存储页面表、请求表以及页表来完成内存的分配工作。
页表:内存中的一块固定存储区。
页式管理时每个进程至少有一个页表。
请求表:用来确定作业或进程的虚拟空间的各页在内存中的实际对应位置;存储页面表:整个系统有一个存储页面表,其描述了物理存储空间的分配使用状况。
操作系统原理-内存分配与回收

内存的动态存储管理一、实验内容编写程序实现动态分区存储管理方式的主存分配与回收。
具体内容包括:首先确定主存空间分配表;然后采用最先适应算法完成主存空间的分配与回收;最后编写主函数对所做工作进行测试二、实验原理模拟存储管理中内存空间的管理和分配内存空间的管理分为固定分区管理方式,可变分区管理方式,页式存储管理,段式存储管理。
题目:模拟内存分配与回收三、实验步骤(或过程)在Microsoft Visual C++ 6.0环境下运行1.设计一个空闲分区表,空闲分区表通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲分区低端的空间。
2.设计一个内存分区表,可用链表管理,用以表示当前以内存使用情况。
3.设计一个进程申请队列以及进程完成后的释放顺序,实现主存的分配和回收。
4.要求每次分配和回收后把空闲分区的变化情况以及各进程的申请、释放情况以及各进程的申请、释放情况以图形方式显示、打印出来。
最佳适应算法:该算法总是把满足要求、又是最小的空闲区分配给作业。
检查空闲区说明表是否有满足作业要求的空闲区,也分为三种情况:大于,等于,小于。
若检查到有“等于”的情况,就可以直接分配,若没有,则继续检查是否有“大于”的情况代码实现如下:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define n 64 //定义内存的大小int a[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数char name[n];//已分配内存的名称(字符类型)typedef struct linknode{char pid;int start;int length;struct linknode *left,*right;}de_node; //进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node *head1,*head2=NULL;struct linknode* creat()//创建一个进程节点{int len,flag1=1;//用于表示进程是否可以创建char id;struct linknode* p;p = (de_node *)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程 if (p==NULL) //p为空,说明系统没有可用内存用于创建此模拟进程{ printf("系统没有足够的内存可供使用!\n");//输出return(NULL);//返回空指针}printf("请输入进程id(字符类型)和长度:");//为进程输入id和分配的长度scanf("%c %d",&id,&len);fflush(stdin);//清除输入缓存if((id>='a'&&id<='z'||id>='A'&&id<='Z')&&(len>0)){for(int i=0;i<count;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf("此名称进程已存在!!");flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);return NULL;}if(len==0) {//如果输入要分配的进程长度为0,释放p,返回空指针printf("输入长度为0!\n");free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p->pid=id; //idp->start=0; //初始开始内存位置,在以后会修改p->length=len;//长度p->left=NULL;//左指针p->right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else {printf("输入进程格式有误\n");free(p);return (NULL);}}//分配内存空间void distribute(de_node *p){ de_node *q=head1,*temp;int flag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q->length>=p->length) {p->start=q->start;//把进程的内存开始地址指向内存的可用开始地址处q->start+=p->length;//可用地址起始改变q->length-=p->length;//可用内存长度修改for(int i=p->start;i<p->start+p->length;i++)//将已分配的内存空间全部置1 a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q->length==0&&q->right!=q){ if(q==head1)//如果第一个满足,修改头指针指向head1=q->right;q->left->right=q->right;q->right->left=q->left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q->right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf("没有满足的内存!\n");count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{ head2=p;//让头指针指向第一个进程p->left=p;//双向队列第一个左右指针都指向自己p->right=p;//双向队列第一个左右指针都指向自己}else if(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向 head2=p;//让头指针指向p指向的进程p->left=temp->left;//p进程左边为原来第一个的左边p->right=temp;//p进程右边指向第一个temp->left->right=p;//原来第一个的左边为ptemp->left=p;//原来第一个的左边的进程为p}}}//对进程的回收void reclaim(){ char id;int flag=0;de_node *q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{ printf("已没有进程!\n");}else {//已分配内存队列如果不为空printf("输入要回收的进程id:");//输入要回收进程的idscanf("%c",&id);fflush(stdin);for(int i=0;i<count;i++)//双重循环把要回收的进程找出来,并把记录的id去掉 if(name[i]==id){//判断当前的进程是否满足要求for(int j=i;j<count;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q->pid==id&&q->right==q&&head2==q){ head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q->pid==id){//如果找到if(q==head2)head2=q->right;q->left->right=q->right;//修改指针指向q->right->left=q->left;flag=1;break;}else q=q->right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0) printf("没有此进程号!!!\n");//没有找到满足的进程if(flag==1){//表示找到了for(int i=q->start;i<q->start+q->length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q->start>p->start&&p->right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p->right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去 q->left=p->left;//修改指针的指向q->right=p;p->left->right=q;p->left=q;if(q->start+q->length==p->start)//可以与后面合并的情况{ q->length+=p->length;//修改指针的指向p->right->left=q;q->right=p->right;free(p);}if(q->left->start+q->left->length==q->start)//可以与前面合并的情况{ q->left->length+=q->length;//修改指针的指向q->left->right=q->right;q->right->left=q->left;free(q);}}}}//打印输出void print(){ de_node *q=head2,*p=head1;if(count==0)printf("没有进程占有内存。
操作系统课程设计-模拟设计页式存储管理的分配与回收范文

学号:28课程设计模拟设计页式存储管理的分题目配与回收学院计算机科学与技术专业计算机科学与技术班级XX姓名XX指导教师XXX2011年01月09日课程设计任务书学生姓名: XX 专业班级:计算机0902班指导教师: XXX 工作单位:计算机科学与技术学院题目: 模拟设计页式存储管理的分配与回收初始条件:1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会页式管理内存的分配和回收过程。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.采用页式管理方案实施内存分配和回收。
能够处理以下的情形⑴能够输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
⑵要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收,撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日武汉理工大学《操作系统》课程设计说明书模拟设计页式存储管理的分配与回收1需求分析页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。
实验二存储器分配与回收

}
}
}
}
voidhuishou(intname){ //回收进程函数
num=0;
b=0;
jishu();
jishu1();
intc=-1;
for(intk=0;k <=b;k++){
if(free[k][0]==name){
c=k;
break;
}
}
if(c==-1)cout<<"要回收的作业不存在!" <<endl;
intidle[10][2]; //空闲区大小地址
intfree[10][3]; //已分配区域的名字地址大小
intnum=0,b=1,d,ch1,ch2;
void init(){
idle[0][0]=1;idle[0][1]=100;
free[0][0]=0;free[1][1]=0;free[1][2]=0;
idle[j+1][1]=temp;
}
}
}
}
voidzuijia(){ //最佳适应法
num=0;
jishu();
for(inti=0;i <num;i++){
for(intj=i;j<num-i-1;j++){
if(idle[j][1]>idle[j+1][1]){
inttemp=idle[j][0];
for(inti=0;i <9;i++)
if(idle[i][1]!=0)
num++;
}
void jishu1(){ //求作业数
操作系统课程设计内存管理

操作系统课程设计内存管理一、课程目标知识目标:1. 理解内存管理的基本概念,掌握内存分配、回收的原理及方法;2. 掌握虚拟内存的原理,了解分页、分段等内存管理技术;3. 了解操作系统中内存保护、共享、碎片处理等相关问题。
技能目标:1. 能够运用所学知识,分析并设计简单的内存管理算法;2. 能够通过编程实践,实现基本的内存分配与回收功能;3. 能够运用虚拟内存技术,解决实际问题。
情感态度价值观目标:1. 培养学生对操作系统中内存管理知识的学习兴趣,激发学生主动探索精神;2. 培养学生的团队协作意识,学会与他人共同解决问题;3. 增强学生的信息安全意识,了解内存管理在操作系统安全中的重要性。
课程性质分析:本课程为操作系统课程设计的一部分,侧重于内存管理方面的知识。
内存管理是操作系统核心功能之一,对于提高系统性能、保障系统安全具有重要意义。
学生特点分析:学生为计算机科学与技术等相关专业的高年级本科生,具备一定的操作系统基础知识,具备一定的编程能力,但可能对内存管理的深入了解和应用尚有不足。
教学要求:1. 结合实际案例,深入浅出地讲解内存管理的基本原理和方法;2. 采用任务驱动法,引导学生通过实践,掌握内存管理技术;3. 注重培养学生的动手能力和创新能力,提高学生解决实际问题的能力。
二、教学内容1. 内存管理概述:介绍内存管理的基本概念、任务和目标;- 教材章节:第2章 内存管理概述- 内容:内存分配、回收原理,内存保护、共享机制。
2. 内存管理技术:讲解物理内存管理和虚拟内存管理技术;- 教材章节:第3章 内存管理技术- 内容:分页管理、分段管理、段页式管理,内存碎片处理。
3. 内存管理算法:分析常见的内存分配和回收算法;- 教材章节:第4章 内存管理算法- 内容:首次适应算法、最佳适应算法、最坏适应算法等。
4. 操作系统内存管理实例分析:结合具体操作系统,分析其内存管理实现;- 教材章节:第5章 操作系统内存管理实例- 内容:Linux内存管理、Windows内存管理。
模拟实现操作系统内存分配与回收的算法背景概述

模拟实现操作系统内存分配与回收的算法背景概述随着计算机技术的不断发展,操作系统在计算机领域中的地位日益凸显。
操作系统作为计算机系统的核心,负责管理硬件资源,包括内存。
内存管理是操作系统的重要任务之一,它涉及到如何有效地分配和回收内存,以满足程序和系统的需求。
在操作系统中,内存管理通常通过虚拟内存和物理内存来实现。
虚拟内存通过地址空间映射将逻辑地址转换为物理地址,以便用户程序可以使用抽象的地址空间来访问物理内存。
物理内存则涉及到实际的物理存储设备的分配和管理。
操作系统中实现内存分配与回收的算法主要依赖于动态内存分配(Dynamic Memory Allocation)机制。
动态内存分配是一种在运行时分配和释放内存的方法,它是操作系统和许多高级编程语言的核心组件。
动态内存分配需要处理的问题包括内存碎片化、内存泄漏和溢出等。
为了解决这些问题,操作系统通常使用一种称为“分页”或“分段”的虚拟内存技术,将物理内存划分为固定大小的页或段,并在需要时进行页面置换或段替换。
本文将介绍一种模拟实现操作系统内存分配与回收的算法背景概述。
我们将从以下几个方面进行阐述:虚拟内存和物理内存的基本概念、动态内存分配机制、页面置换算法以及内存回收策略。
首先,虚拟内存和物理内存是操作系统中处理内存分配和回收的基本概念。
虚拟内存通过地址空间映射将程序的逻辑地址转换为物理地址,以实现抽象的地址空间访问物理内存。
这样可以隐藏物理内存的复杂性,并为程序员提供一种简单的方式来管理内存。
物理内存则是指实际的物理存储设备,如RAM、硬盘等。
动态内存分配是操作系统中实现内存管理的关键技术之一。
它允许程序在运行时请求和释放内存,避免了静态内存分配的局限性,如静态分配的内存不能重复使用,需要手动释放等。
动态内存分配通常使用数据结构如链表、哈希表等来跟踪分配的内存块,并使用垃圾收集机制来自动回收不再使用的内存。
页面置换算法是操作系统中实现动态内存分配的核心技术之一。
操作系统课程设计 主存的分配与回收

存档资料成绩:华东交通大学理工学院课程设计报告书所属课程名称计算机操作系统题目主存空间的分配与回收分院电信分院专业班级计算机科学与技术(1)班学号学生姓名指导教师2012 年 6 月20 日目录第1章课程设计内容及要求. (3)第2章需求分析 (4)第3章概要设计 (5)第4章详细设计 (8)第5章调试分析与测试结果 (11)第6章课程设计心得 (16)第7章参考文献 (17)附录 (18)第一章课程设计内容及要求1.1 课程设计的目的通过该课程设计使学生理解在不同的存储管理方式下,以及使学生加深对如何实现主存空间的分配与回收原理的理解。
也使学生初步具有研究、设计、编制和调试操作系统模块的能力。
1.2 课程设计内容主存是中央处理器能直接存取指令和数据的存储器,能否合理地利用主存,在很大程度上将影响到整个计算机的性能。
通过本次实验可以帮助理解主存空间的分配与回收的几种算法:①掌握最先适应分配算法;②掌握最优适应分配算法;③掌握最坏适应分配算法。
第二章需求分析2.1 软件及硬件需求适用于现在各种计算机,建议内存不少于128M。
开发环境:VMware虚拟机软件,ubuntu 11.10系统,Gcc编译器。
2.2 设计需求内存的分配与回收是内存管理的主要功能之一。
无论采取哪一种管理和控制方式,能否把外存中的数据和程序调入内存,取决于内否在内存中为他们安排合适的位置。
因此,存储管理模块要为每一个并发执行的进程分配内存空间。
另外,当进程执行结束之后,存储管理模块又要及时回收该进程所占用的内存资源,以便给其他进程分配空间。
但由于作业大大小不一,所以系统为作业分配内存大小不一,在释放时造成系统资源的浪费。
因此,采取首次适应算法,以及那少内存的浪费。
第三章概要设计3.1 设计思想初始化系统的内存分区说明表;输入当前作业或进程的使用内存情况,检索系统内的内存分区说明表,判断是否可分配,也就是查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若无;则作业等待。
操作系统实验二存储管理动态分区分配及回收算法

实验二存储管理动态分区分配及回收算法一、实验目的通过分区管理实验,了解操作系统的基本概念,理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。
通过课程设计,我们可以进一步理解在计算机系统上运行的其它各类操作系统,并懂得在操作系统的支持下建立自己的应用系统。
二、实验要求本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法和回收算法模拟程序,并掌握分配算法的特点,提高编程技巧和对算法的理解和掌握。
三、实验过程1.准备(一)主程序1、定义分区描述器node,包括 3个元素:(1)adr——分区首地址(2)size——分区大小(3)next——指向下一个分区的指针2、定义 3个指向node结构的指针变量:(1)head1——空闲区队列首指针(2)back1——指向释放区node结构的指针(3)assign——指向申请的内存分区node结构的指针3、定义 1个整形变量:free——用户申请存储区的大小(由用户键入)(二)过程1、定义check过程,用于检查指定的释放块(由用户键入)的合法性2、定义assignment1过程,实现First Fit Algorithm3、定义assignment2过程,实现Best Fit Algorithm4、定义acceptment1过程,实现First Fit Algorithm的回收算法5、定义acceptment2过程,实现Best Fit Algorithm的回收算法6、定义print过程,打印空闲区队列(三)执行程序首先申请一整块空闲区,其首址为0,大小为32767;然后,提示用户使用哪种分配算法,再提示是分配还是回收;分配时要求输入申请区的大小,回收时要求输入释放区的首址和大小。
(四)输出要求每执行一次,输出一次空闲区队列情况,内容包括:编号首址终址大小2.主要流程和源代码实验二源代码#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 32767typedef struct node {int id;int adr;int size;struct node *next;}Node;Node *head1,*head2,*back1,*back2,*assign;int request;int check(int add,int siz,char c){Node *p,*head;int check=1;if(add<0||siz<0)check=0;/*地址和大小不能为负*/if(c=='f'||c=='F')head=head1;elsehead=head2;p=head->next;while((p!=NULL)&&check)if(((add<p->adr)&&(add+siz>p->adr))||((add>=p->adr)&&(add<p->adr+p->size))) check=0;elsep=p->next;if(check==0)printf("\t输入释放区地址或大小有错误!!!\n");return check;}void init(){Node *p;head1=(Node*)malloc(sizeof(Node));head2=(Node*)malloc(sizeof(Node));p=(Node*)malloc(sizeof(Node));head1->next=p;head2->next=p;p->size=MAX_SIZE;p->adr=0;p->next=NULL;p->id=0;}Node* assignment1(int num,int req){Node *before,*after,*ass;ass=(Node*)malloc(sizeof(Node));before=head1;after=head1->next;ass->id=num;ass->size=req;while(after->size<req){before=before->next;after=after->next;}if(after==NULL){ass->adr=-1; }else{if(after->size==req){before->next=after->next;ass->adr=after->adr;}else{after->size-=req;ass->adr=after->adr;after->adr+=req;}}return ass;}void acceptment1(int address,int siz,int rd){Node *before,*after;int insert=0;back1=(Node*)malloc(sizeof(Node));before=head1;after=head1->next;back1->adr=address;back1->size=siz;back1->id=rd;back1->next=NULL;while(!insert&&after){//将要被回收的分区插入空闲区(按首址大小从小到大插入)if((after==NULL)||((back1->adr<=after->adr)&&(back1->adr>=before->adr))) {before->next=back1;back1->next=after;insert=1;}else{before=before->next;after=after->next;}}if(insert){if(back1->adr==before->adr+before->size){//和前边分区合并before->size+=back1->size;before->next=back1->next;free(back1);}else if(after&&back1->adr+back1->size==after->adr){//和后边分区合并back1->size+=after->size;back1->next=after->next;back1->id=after->id;free(after);after=back1;}printf("\t首先分配算法回收内存成功!\n");}elseprintf("\t首先分配算法回收内存失败!\n");}Node* assignment2(int num,int req){Node *before,*after,*ass,*q;ass=(Node*)malloc(sizeof(Node));q=(Node*)malloc(sizeof(Node));before=head2;after=head2->next;ass->id=num;ass->size=req;while(after->size<req){before=before->next;after=after->next;}if(after==NULL){ass->adr=-1;}else{if(after->size==req){before->next=after->next;ass->adr=after->adr;}else{q=after;before->next=after->next;ass->adr=q->adr;q->size-=req;q->adr+=req;before=head2;after=head2->next;if(after==NULL){before->next=q;q->next=NULL;}else{while((after->size)<(q->size)){before=before->next;after=after->next;}before->next=q;q->next=after;}}}return (ass);}void acceptment2(int address,int siz,int rd) {Node *before,*after;int insert=0;back2=(Node*)malloc(sizeof(Node)); before=head2;after=head2->next;back2->adr=address;back2->size=siz;back2->id=rd;back2->next=NULL;if(head2->next==NULL){//空闲队列为空head2->next=back2;head2->size=back2->size;}else{//空闲队列不为空while(after){if(back2->adr==after->adr+after->size) {//和前边空闲分区合并before->next=after->next;after->size+=back2->size;back2=after;}else{before=before->next;after=after->next;}}before=head2;after=head2->next;while(after){if(after->adr==back2->adr+back2->size) {//和后边空闲区合并before->next=after->next;back2->size+=after->size;}else{before=before->next;after=after->next;}}before=head2;after=head2->next;while(!insert){//将被回收的块插入到恰当的位置(按分区大小从小到大)if(after==NULL||((after->size>back2->size)&&(before->size<back2->size))) {before->next=back2;back2->next=after;insert=1;break;}else{before=before->next;after=after->next;}}}if(insert)printf("\t最佳适应算法回收内存成功!\n");elseprintf("\t最佳适应算法回收内存失败!!\n");}void print(char choice)//输出空闲区队列信息{Node *p;if(choice=='f'||choice=='F')p=head1->next;elsep=head2->next;if(p){printf("\n空闲区队列的情况为:\n");printf("\t编号\t首址\t终址\t大小\n");while(p){printf("\t%d\t%d\t%d\t%d\n",p->id,p->adr,p->adr+p->size-1,p->size);p=p->next;}}}void menu()//菜单及主要过程{char chose;int ch,num,r,add,rd;while(1){system("cls");printf("选择最先适应算法请输入F,选择最佳适应算法请输入B,退出程序请输入E\n\n"); printf("请输入你的选择:");scanf("%c",&chose);if(chose=='e'||chose=='E')exit(0);else{system("cls");while(1){if(chose=='f'||chose=='F')printf("最先适应算法(First-Fit)模拟:\n");if(chose=='b'||chose=='B')printf("最佳适应算法(Best-Fit)模拟:\n");printf("1.分配内存,2.回收内存,3.查看内存,4.返回\n\n");printf("请输入你的选择:");scanf("%d",&ch);fflush(stdin);switch(ch){case 1:printf("输入申请的分区大小:");scanf("%d",&r);if(chose=='f'||chose=='F')assign=assignment1(num,r);elseassign=assignment2(num,r);if(assign->adr==-1){printf("分配内存失败!\n");}elseprintf("分配成功!分配的内存的首址为:%d\n",assign->adr);break;case 2:printf("输入释放的内存的首址:");scanf("%d",&add);printf("输入释放的内存的大小:");scanf("%d",&r);printf("输入释放的内存的编号:");scanf("%d",&rd);if(check(add,r,chose)) {if(chose=='f'||chose=='F') acceptment1(add,r,rd); elseacceptment2(add,r,rd);}break;case 3:print(chose);break;case 4:menu();break;}}}}}void main()//主函数{init();menu();}四、实验结果五、实验总结通过这次课程设计我练习了用C语言写系统软件,对操作系统中可变分区存储管理有了更深刻的了解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学号:0120910340228课程设计模拟设计页式存储管理的分题目配与回收学院计算机科学与技术专业计算机科学与技术班级XX姓名XX指导教师XXX2011 年01 月09 日课程设计任务书学生姓名:XX 专业班级:计算机0902班指导教师:XXX 工作单位:计算机科学与技术学院题目: 模拟设计页式存储管理的分配与回收初始条件:1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会页式管理内存的分配和回收过程。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.采用页式管理方案实施内存分配和回收。
能够处理以下的情形⑴能够输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
⑵要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收,撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日模拟设计页式存储管理的分配与回收1需求分析页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。
基本原理是将各进程的虚拟空间划分成若干个长度相等的页(page),页式管理把内存空间按页的大小划分成片或者页面(page frame),然后把页式虚拟地址与内存地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
页式管理采用请求调页或预调页技术实现了内外存存储器的统一管理。
图1 页的划分图2 基本页表示例静态分页管理的第一步是为要求内存的作业或进程分配足够的页面。
系统通过存储页面表、请求表以及页表来完成内存的分配工作。
页表指的是内存中的一块固定存储区。
页式管理时每个进程至少有一个页表。
请求表指的是用来确定作业或进程的虚拟空间的各页在内存中的实际对应位置;另外整个系统有一个存储页面表,其描述了物理内存空间的分配使用状况。
图3 请求表的示例存储页面表有两种构成方法:1、位示图法2、空闲页面链表法模拟设计页式存储管理的分配与回收要求能够满足如下的要求:(1)输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
(2)要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2 功能设计2.1 算法分析首先,请求表给出进程或作业要求的页面数。
然后,由存储页面表检查是否有足够的空闲页面,如果没有,则本次无法分配。
如果有则首先分配设置页表,并请求表中的相应表项后,按一定的查找算法搜索出所要求的空闲页面,并将对应的页好填入页表中。
图4 分配页面的算法流程2.2 数据结构页式管理把内存空间按页的大小划分成片或者页面,再按照一定的规律建立起页表,并通过请求表将分配内容显示出来.将页表和请求表的内容使用结构体来定义是比较方便的.//页表项结构typedef struct _pagetableitem{pageid pagenum; //页号blockid blocknum; //块号}pgtabitem; //页表typedef pgtabitem * pagetable;//请求表结构typedef struct _reqtable{unsigned pid; //进程号unsigned reqpagenum; //请求页面数pagetable pgtabadr; //页表始址bool state; //状态} reqtabitem;请求表还引入了支持快速插入和删除的list顺序容器来进行相关操作.list<reqtabitem> reqtable因为模拟设计的关系,页面的起始地址均应该为随机的数值,所以程序在设计过程中加入了随机数类的编写.class RandomNumber{private:unsigned long randseed;public:RandomNumber(unsigned long s=0);unsigned short Random(unsigned long n);double fRandom(void);};采用当前系统的时间值来生成伪随机数分配地址.定义随机数产生器:RandomNumber random定义内存页面数:int pagenum定义页面大小:int pagesize定义进程个数:int pnum用整数数组模拟分配的内存页面数int * mempage=new int[pagenum]2.3模块说明2.3.1 主函数主函数依次运行了程序中所实现的关键函数.int main(){InitSys(); //初始化系统MainChoice();//输出系统菜单Destroy(); //释放申请的动态内存return 0;}2.3.2 各个功能函数初始化内存页面:void Init_Mempage(void)获取内存使用情况:int Get_Mempagenum(void) 初始化默认的请求表:void Init_Reqtable(void) 为默认的进程分配内存:void Init_DistMem(void) 手动创建进程,并分配内存:void Dist_Mem(void) 释放申请的动态内存:void Destroy(void)结束指定进程:void Kill(void)2.3.3 打印函数打印出进程请求表:void PrintReqtable(void)打印出页表:void PrintPageTable(void)打印出内存使用情况:void PrintMem(void)打印出物理块的大小:void PrintBlockSize(void)2.3.4 其他函数初始化系统: void InitSys(void)输出主菜单:void MainMenu(void)选择运行分支:void MainChoice()3开发平台3.1开发平台(1)使用系统:Windows 7(2)使用语言:C++(3)开发工具:Visual C++ 20084测试用例,运行结果与运行情况分析4.1测试方法通过输入正常数据以及非正常数据对程序进行全方位测试4.2测试结果(1)程序主界面(2)输入进程号和页面数:(3)显示进程页表:(4)显示请求表(5)显示内存使用情况以及物理块大小(6)错误检验5源程序的主要部分#include <iostream>#include <cstdlib>#include <iomanip>#include <list>#include "page.h"#include "Random.h"using namespace std;list<reqtabitem> reqtable;RandomNumber random; //随机数产生器unsigned pagenum=random.Random(80)+21; //内存页面数21-100 unsigned pagesize=random.Random(16)+5; //页面大小5-20unsigned pnum=random.Random(4)+5;//进程的个数5-8int * mempage=new int[pagenum]; //用整数数组模拟内存页面数/*初始化内存页面*/void Init_Mempage(void){int i=0;for(i=0;i<int(pagenum);i++)mempage[i]=0; //数组全部赋初值}/*获取内存的使用情况*/int Get_Mempagenum(void){int sum=0;for(int i=0;i<int(pagenum);i++)if(mempage[i]==0)sum++;return sum; //判断有多少内存页面已经被使用}/*初始化默认的请求表*/void Init_Reqtable(void){int i;for(i=1;i<=int(pnum);i++){reqtabitem preq;preq.pid=i;preq.reqpagenum=random.Random(4)+2;//进程请求的页面大小-5preq.state=false;preq.pgtabadr=NULL;reqtable.push_back(preq); //依次压入容器}}/*为默认的进程分配内存*/void Init_DistMem(void){int reqpnum; //进程请求页面数int i;list<reqtabitem>::iterator pos=reqtable.begin();for(;pos!=reqtable.end();pos++){reqpnum=(*pos).reqpagenum;if(reqpnum>int(Get_Mempagenum())) //判断请求的内存页面数目是否大于剩余的{cout<<"没有足够的内存!"<<endl;cout<<endl;}else{(*pos).state=true;pagetable temp = new pgtabitem[reqpnum]; //新建临时页表项数组if(temp==NULL){cout<<"内存分配失败!"<<endl;exit(0);}(*pos).pgtabadr=temp;for(i=0;i<reqpnum;i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}}}/*手动创建进程,并分配内存*/void Dist_Mem(void){int i;reqtabitem preq; //新创建进程记录int pid; //进程号int reqpnum; //请求页面数bool flag=false;do{cout<<"请输入进程号:";flag=false;cin>>pid;for(list<reqtabitem>::iteratorpos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid){flag=true;cout<<"该进程号已经存在,请重新输入"<<endl;cout<<endl;break;}}}while(flag==true); //循环直到输入的Pid满足条件preq.pid=pid;cout<<"请输入需要的页面数:";cin>>reqpnum;preq.reqpagenum=reqpnum;preq.state=false;preq.pgtabadr=NULL;reqpnum=preq.reqpagenum;if(reqpnum>Get_Mempagenum()){cout<<"没有足够的内存,进程创建失败!"<<endl;cout<<endl;}else{preq.state=true;pagetable temp = new pgtabitem[reqpnum];if(temp==NULL){cout<<"内存分配失败!"<<endl;exit(0);}preq.pgtabadr=temp;for(i=0;i<int(reqpnum);i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}reqtable.push_back(preq); //将该进程的记录加入请求表}/*程序结束时,释放申请的动态内存*/void Destroy(void){list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).state==true)delete [](*pos).pgtabadr;}reqtable.clear();}/* 打印出进程请求表*/void PrintReqtable(void){cout<<endl;cout<<"|--------------------------------------------------------------------|"<<endl;cout<<"| 进程请求表|"<<endl;cout<<"|--------------------------------------------------------------------|"<<endl;cout<<"|"<<setw(8)<<"进程号"<<setw(16)<<"请求页面数"<<setw(16)<<"页表起始地址"<<setw(16)<<"页表长度"<<setw(16)<<"状态|"<<endl;cout<<"|---------------------------------------------------------------------|"<<endl;list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){cout<<"|"<<setw(8)<<(*pos).pid<<setw(16)<<(*pos).reqpagenum<<setw(16)<<(*pos).pgtabadr<<setw(16)<<((*pos).reqpagenum) * pagesize;if((*pos).state)cout<<setw(4)<<"已分配|"<<endl;elsecout<<setw(4)<<"未分配|"<<endl;if((*pos).pid!=reqtable.back().pid)cout<<"|--------------------------------------------------------------------|"<<endl;elsecout<<"|--------------------------------------------------------------------|"<<endl;}}/*打印页表*/void PrintPageTable(void){unsigned pid;int i;bool flag=false;cout<<"请输入进程号:";cin>>pid;list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid&&(*pos).state==true){flag=true;cout<<"|---------------------------|"<<endl;cout<<"| 此进程的页表|"<<endl;cout<<"|---------------------------|"<<endl;cout<<"|"<<setw(16)<<"页号"<<setw(6)<<"块号|"<<endl;cout<<"|---------------------------|"<<endl;int reqpagenum=(*pos).reqpagenum;for(i=0;i<reqpagenum;i++){cout<<"|"<<setw(16)<<(*pos).pgtabadr[i].pagenum<<setw(6)<<(*pos).pgtabadr[i].blocknum<<"|"<<endl;if(i!=reqpagenum-1)cout<<"|---------------------------|"<<endl;elsecout<<"|---------------------------|"<<endl;}}}if(flag==false)cout<<"系统中不存在该进程或者该进程还没有被分配内存!\n";cout<<endl;}void PrintMem(void){cout<<"内存总块数为"<<pagenum<<",已经使用了"<<pagenum-Get_Mempagenum()<<"块!"<<endl;cout<<"现在还有"<<Get_Mempagenum()<<"块内存区域空闲!"<<endl;cout<<endl;}void PrintBlockSize(void){cout<<"物理块大小为:"<<pagesize<<"KB"<<endl;cout<<endl;}/*结束指定进程*/void Kill(void){bool flag;int i;reqtabitem temp;list<reqtabitem>::iterator pos=reqtable.begin();int pid;do{cout<<"请输入进程号:";flag=false;cin>>pid;for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid){flag=true;temp=*pos;break;}}if(flag==false)cout<<"系统中不存在该进程!"<<endl;cout<<endl;}while(flag==false);for(i=0;i<int(temp.reqpagenum);i++)mempage[temp.pgtabadr[i].blocknum]=0;reqtable.remove(temp);//重新为没有分配到内存的进程分配内存for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).state==false){int reqpnum;reqpnum=(*pos).reqpagenum;if(reqpnum<=Get_Mempagenum()){(*pos).state=true;pagetable temp = new pgtabitem[reqpnum];if(temp==NULL){cout<<"内存分配失败!"<<endl;cout<<endl;exit(0);}(*pos).pgtabadr=temp;for(i=0;i<int(reqpnum);i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}}}}/*初始化系统*/void InitSys(void){cout.setf(ios::left);//左对齐Init_Mempage();Init_Reqtable();Init_DistMem();}/*输出主菜单*/void MainMenu(void){cout<<"页式存储管理的分配与回收"<<endl;cout<<"1.手动创建进程"<<endl;cout<<"2.显示进程页表"<<endl;cout<<"3.显示请求表"<<endl;cout<<"4.撤销进程"<<endl;cout<<"5.显示内存使用情况"<<endl;cout<<"6.显示物理块大小"<<endl;cout<<"7.退出系统"<<endl;cout<<"请输入您的选择(0--7):";}/*选择函数*/void MainChoice(){int choice;do{MainMenu();cin>>choice;switch(choice){case 1:Dist_Mem();break;case 2:PrintPageTable();break;case 3:PrintReqtable();break;case 4:Kill();break;case 5:PrintMem();break;case 6:PrintBlockSize();break;case 7:break;default :cout<<"输入有误,请重新输入.\n";cout<<endl;break;}}while(choice!=7);}int main(){InitSys();//初始化系统MainChoice();//输出系统菜单Destroy();//释放申请的动态内存return 0;}6自我评价与总结此次试验是完全在自己独立完成的,首先在分析问题并把问题转化为编程问题,我觉得个人把握的很好,对页式管理的基本原理理解的比较透彻;其次我用了个随机函数来模拟页表起始地址和物理块大小等变量,使得输出的结果显得随机性较强,符合系统真实分配的情况. 另外对于进程请求表使用顺序容器操作,结构体保存项目的设计也独具匠心,配合迭代器的使用达到类似栈的用途,输出请求表的时候比较清晰明了.但是程序还有不足之处,程序仅仅只能从直观数值上来体现页式管理的随机分配的特性,并没有办法像linux之类操作系统一般真正的进行内存分配与回收,这是课后深入研究的一个方面。