模拟实现一个简单的可变分区存储管理系统

合集下载

操作系统实验-可变分区存储管理

操作系统实验-可变分区存储管理

作业一实验一 :可变分区存储管理(一) 实验题目编写一个C 程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),模拟可变分区内存管理,实现对该内存区的分配和释放管理。

(二) 实验目的1.加深对可变分区的存储管理的理解;2.提高用C 语言编制大型系统程序的能力,特别是掌握C 语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。

(三)程序代码 #include<malloc.h> #include<stdio.h> #include<string.h>#define new(type) (type *)malloc(sizeof(type))typedef struct _map {unsigned int size; char *address; struct _map *next; struct _map *prev;(a)(b)(c)(d)图2-9释放区与前后空闲区相邻的情况} map;typedef map *pmap;typedef struct _mem{unsigned int totalSize;char* space;pmap head;pmap cMap;} mem;typedef mem *pmem;pmem createMem(unsigned int to_size) //创建内存区域{pmem newMem=new(mem);pmap newHead=new(map);newMem->totalSize=to_size;newHead->size=to_size;newHead->address=newMem->space;newHead->next=newHead;newHead->prev=newHead;newMem->head=newHead;newMem->cMap=newHead;return newMem;}void freeMem(pmem m){pmap map,cMap;pmap head=m->head;free(map->address);for(map=head;map->next!=head;){cMap=map;map=cMap->next;free(cMap);}free(m);}char* lmalloc(pmem cMem,unsigned int size) //分配函数{if(size>1000){printf("内存容量超出范围!\n"); //当需要分配的内存空间已经大于实际空间时出错}else{pmap p=cMem->cMap;char* rAddr;if(size==0)return NULL;while(p->size<size){if(p->next==cMem->cMap)return NULL;p=p->next;}rAddr=p->address;p->size-=size;p->address+=size;if(p->size==0){p->prev->next=p->next;p->next->prev=p->prev;cMem->cMap=p->next;if(cMem->head==p)cMem->head=p->next;if(p->next!=cMem->head)free(p);}else{cMem->cMap=p;}return rAddr;}}void lfree(pmem m,unsigned int size,char* addr) //释放函数{pmap nextMap,prevMap,newMap;if(addr<m->space || addr>=m->space+m->totalSize){fprintf(stderr,"地址越界\n"); //释放空间时,大小输入出错return;}nextMap=m->head;while(nextMap->address<addr){nextMap=nextMap->next;if(nextMap==m->head)break;}prevMap=nextMap->prev;if(nextMap!=m->head && prevMap->address+prevMap->size==addr) //第一种情况{prevMap->size+=size;if(addr+size==nextMap->address) //第二种情况{prevMap->size+=nextMap->size;prevMap->next=nextMap->next;prevMap->next->prev=prevMap;if(nextMap==m->cMap){m->cMap=prevMap;}free(nextMap);nextMap=NULL;}}else{if(addr+size==nextMap->address) //第三种情况{nextMap->address-=size;nextMap->size+=size;}else //第四种情况{newMap=new(map);newMap->address=addr;newMap->size=size;prevMap->next=newMap;newMap->prev=prevMap;newMap->next=nextMap;nextMap->prev=newMap;if(nextMap==m->head)m->head=newMap;}}}void printMem(pmem m) //打印函数{pmap map=m->head;printf("\空闲内存空间:\n\-----------------------\n\大小起始地址\n");do{if(map==m->cMap)printf("-> ");elseprintf(" ");printf("%10u %10u\n",map->size,map->address);map=map->next;}while(map!=m->head);printf("-----------------------\n");}void main() //主函数{printf("--------------------------------------------------------\n");printf("请选择操作:分配内存(m) or 释放内存(f) or 打印内存表(p)\n");printf("--------------------------------------------------------\n");typedef enum{cmdMalloc,cmdFree,cmdPrint,cmdHelp,cmdQuit,cmdInvalid} cmdType; pmem m=createMem(1000);char cmd[20];char *addr;unsigned int size;cmdType type;while(1){scanf("%s",cmd);if(cmd[1]=='\0'){switch(cmd[0]){case 'm':case 'M':type=cmdMalloc;break;case 'f':case 'F':type=cmdFree;break;case 'p':case 'P':type=cmdPrint;break;}}else{if(!strcmp(cmd,"malloc"))type=cmdMalloc;else if(!strcmp(cmd,"free"))type=cmdFree;else if(!strcmp(cmd,"print"))type=cmdPrint;}switch(type){case cmdMalloc:scanf("%u",&size);lmalloc(m,size);printMem(m);break;case cmdFree:scanf("%u %u",&size,&addr);lfree(m,size,addr);printMem(m);break;case cmdPrint:printMem(m);break;return;}}}(四)程序结果。

3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理可变式分区存储管理是一种动态分配内存空间的方式,它能够根据进程的内存需求来动态地分配和回收内存空间,提高内存的利用率。

在C语言中,我们可以使用指针和数据结构来模拟实现可变式分区存储管理。

1.使用结构体来表示内存块首先,我们可以定义一个结构体来表示每个内存块的属性,包括起始地址、大小、以及是否被占用等信息。

```cstruct Blockint start_address;int size;int is_allocated; // 0代表未分配,1代表已分配};```2.初始化内存空间接下来,我们可以定义一个数组来表示整个内存空间,该数组的每个元素都是一个 Block 结构体,表示一个内存块。

在程序开始时,我们可以初始化一个 Block 数组,表示整个内存空间的初始状态。

```c#define TOTAL_SIZE 1024 // 内存总大小struct Block memory[TOTAL_SIZE];void init_memormemory[0].start_address = 0;memory[0].size = TOTAL_SIZE;memory[0].is_allocated = 0;```3.分配内存空间当进程需要分配内存空间时,可变式分区存储管理会选择一个合适的内存块来分配给该进程。

我们可以定义一个函数来实现分配内存的过程。

```cint allocate_memory(int size)int i;for (i = 0; i < TOTAL_SIZE; i++)if (!memory[i].is_allocated && memory[i].size >= size)//找到未分配且大小足够的内存块memory[i].is_allocated = 1;memory[i].size -= size;return memory[i].start_address;}}//没有找到合适的内存块return -1;```4.回收内存空间当进程释放已分配的内存空间时,我们需要回收这部分内存,使其变为未分配状态。

可变分区管理实验

可变分区管理实验

实验三、可变分区内存管理实验环境:实验环境一:Windows平台实验时间:6小时实验目的:体会可变分区内存管理方案,掌握此方案的内存分配过程、内存回收过程和紧凑算法的实现。

实验目标:编制一个程序模拟实现可变分区内存管理。

实验时,假设系统内存容量为1000KB。

分配时使用malloc(pid, length)函数实现,作业释放内存时使用mfree(handle)函数实现,内存情况输出用mlist()函数实现。

实验步骤:1、编写主界面,界面上有三个选项:分配内存、回收内存、查看内存。

选择分配内存时,要求输入作业的进程号和作业长度,然后使用malloc函数分配内存,并报告内存分配结果。

回收内存时要求输入进程号,使用mfree函数实现回收。

查看内存时,使用mlist函数实现输出内存使用情况和空闲情况。

2、编写malloc(pid, length)函数,实现进程pid申请length KB内存,要求程序判断是否能分配,如果能分配,要把分配内存的首地址handle输出到屏幕上。

不能分配则输出字符串“NULL”。

要考虑不能简单分配时,是否符合紧凑的条件,如符合则采用紧凑技术,然后再分配。

分配时可在最佳适应算法、最差适应算法和首次适应算法中任选其一。

3、编写mfree(handle)函数,释放首地址为handle的内存块。

释放成功返回Success,否则返回Failure。

4、编写mlist()函数,要求输出内存使用情况和空闲情况。

输出的格式为:ID Address Length ProcessID 内存分区号Address 该分区的首地址Length 分区长度Process 如果使用,则为使用的进程号,否则为NULL实验结果:实验步骤2的实现过程是:实验步骤2中紧凑算法是如何实现的?实验步骤3中分别要考虑多少种情况?实验步骤3的实现过程是:实验步骤4的实现过程是:实验步骤4的结果是什么?实验报告:(1)完成实验结果中的问题。

模拟实现一个简单的固定(可变)分区存储管理系统

模拟实现一个简单的固定(可变)分区存储管理系统

合肥学院计算机科学与技术系实验报告2009~2010学年第一学期课程操作系统原理实验名称模拟实现一个简单的固定(可变)分区存储管理系统学生姓名朱海燕、汪小白、秦月、程美玲专业班级07计本(1)班指导教师屠菁2009年12月1.实验目的通过本次课程设计,掌握了如何进行内存的分区管理,强化了对首次适应分配算法和分区回收算法的理解。

2.实验内容(1)建立相关的数据结构,作业控制块、已分配分区及未分配分区(2)实现一个分区分配算法,如最先适应算法、最优或最坏适应分配算法(3)实现一个分区回收算法(4)给定一个作业/进程,选择一个分配或回收算法,实现分区存储的模拟管理3.实验步骤首先,初始化函数initial()将分区表初始化并创建空闲分区列表,空闲区第一块的长度是30,以后的每个块长度比前一个的长度长20。

frees[0].length=30第二块的长度比第一块长20,第三块比第二块长30,以此类推。

frees[i].length=frees[i-1].length+20;下一块空闲区的首地址是上一块空闲区的首地址与上一块空闲区长度的和。

frees[i].front=frees[i-1].front+frees[i-1].length;分配区的首地址和长度都初始化为零occupys[i].front=0;occupys[i].length=0;显示函数show()是显示当前的空闲分区表和当前的已分配表的具体类容,分区的有起始地址、长度以及状态,利用for语句循环输出。

有一定的格式,使得输出比较美观好看。

assign()函数是运用首次适应分配算法进行分区,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲链中。

若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。

这个算法倾向于优先利用内存中低址部分被的空闲分区,从而保留了高址部分的的大空闲区。

可变分区存储管理的内存分配算法模拟实现----最佳适应算法

可变分区存储管理的内存分配算法模拟实现----最佳适应算法

可变分区存储管理的内存分配算法模拟实现----最佳适应算法可变分区存储管理是一种内存管理技术,其通过将内存分割成不同大小的区域来存储进程。

每个进程被分配到与其大小最匹配的区域中。

内存分配算法的选择影响了系统的性能和资源利用率。

本文将介绍最佳适应算法,并模拟实现该算法。

一、什么是最佳适应算法?最佳适应算法是一种可变分区存储管理中的内存分配策略。

它的基本思想是在每次内存分配时选择最合适的空闲区域。

具体来说,它从可用的空闲区域中选择大小与需要分配给进程的内存最接近的区域。

二、算法实现思路最佳适应算法实现的关键是如何快速找到最合适的空闲区域。

下面给出一个模拟实现的思路:1. 初始化内存分区列表,首先将整个内存定义为一个大的空闲区域。

2. 当一个进程请求分配内存时,从列表中找到与所需内存最接近的空闲区域。

3. 将该空闲区域分割成两部分,一部分分配给进程,并将该部分标记为已分配,另一部分留作新的空闲区域。

4. 更新内存分区列表。

5. 当一个进程释放内存时,将其所占用的内存区域标记为空闲,然后尝试合并相邻的空闲区域。

三、算法模拟实现下面是一个简单的Python代码实现最佳适应算法:pythonclass MemoryPartition:def __init__(self, start_addr, end_addr, is_allocated=False): self.start_addr = start_addrself.end_addr = end_addrself.is_allocated = is_allocatedclass MemoryManager:def __init__(self, total_memory):self.total_memory = total_memoryself.partition_list = [MemoryPartition(0, total_memory)]def allocate_memory(self, process_size):best_fit_partition = Nonesmallest_size = float('inf')# 找到最佳适应的空闲区域for partition in self.partition_list:if not partition.is_allocated and partition.end_addr - partition.start_addr >= process_size:if partition.end_addr - partition.start_addr < smallest_size:best_fit_partition = partitionsmallest_size = partition.end_addr - partition.start_addrif best_fit_partition:# 将空闲区域分割,并标记为已分配new_partition =MemoryPartition(best_fit_partition.start_addr,best_fit_partition.start_addr + process_size, True)best_fit_partition.start_addr += process_sizeself.partition_list.append(new_partition)return new_partition.start_addr,new_partition.end_addrelse:return -1, -1def deallocate_memory(self, start_addr, end_addr):for partition in self.partition_list:if partition.start_addr == end_addr and not partition.is_allocated:# 标记空闲区域partition.is_allocated = False# 尝试合并相邻空闲区域for next_partition in self.partition_list:if not next_partition.is_allocated andnext_partition.start_addr == end_addr:end_addr = next_partition.end_addrself.partition_list.remove(next_partition)breakelse:breakdef print_partitions(self):for partition in self.partition_list:if partition.is_allocated:print(f"Allocated Partition: {partition.start_addr} - {partition.end_addr}")else:print(f"Free Partition: {partition.start_addr} - {partition.end_addr}")# 测试最佳适应算法if __name__ == "__main__":mm = MemoryManager(1024)start, end = mm.allocate_memory(256)print(f"Allocated memory: {start} - {end}")mm.print_partitions()mm.deallocate_memory(start, end)print("Memory deallocated:")mm.print_partitions()以上代码实现了一个简单的内存管理器类`MemoryManager`,它具有`allocate_memory`和`deallocate_memory`等方法。

模拟实现可变分区存储管理

模拟实现可变分区存储管理

《操作系统》课程设计说明书题目:模拟实现可变分区存储管理班级:学号:姓名:指导老师:1.目的和要求在熟练掌握计算机分区存储管理方式的原理的基础上,利用一种程序设计语言模拟实现操作系统的可变分区存储管理的功能,一方面加深对原理的理解,另一方面提高学生通过编程根据已有原理解决实际问题的能力,为学生将来进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。

2.设计内容设计合理的数据结构来描述存储空间:对于未分配出去的部分,可以用空闲分区队列或空闲分区链表来描述,对于已经分配出去的部分,由装入内存的作业占据,可以将作业组织成链表或数组。

实现分区存储管理的内存分配功能,实现两种适应算法:首次适应算法,最坏适应算法。

实现分区存储管理的内存回收算法:要求能够正确处理回收分区与空闲分区的四种邻接关系。

当碎片产生时,能够进行碎片的拼接。

3.设计环境Windows操作系统、DEV C++C语言4.程序概要(1)数据结构和全局变量int type = 0; //算法类型//空闲分区struct freelink {int len; //len为分区长度int address; //address为分区起始地址struct freelink *next;};//占用分区struct busylink {char name; //作业或进程名,name='S' 表示OS占用int len;int address;struct busylink *next;};struct freelink *free_head = NULL; //自由链队首指针struct busylink *busy_head = NULL, //占用区队首指针*busy_tail = NULL; //占用区队尾指针(2)功能模块划分大体上可以将整个程序的模块划分成如下几个部分:1)主模块:主要是初始化(设置物理内存的用户区的大小,选取适应算法)和界面,界面参考如下:2)内存分配算法(实现两种适应算法:最坏适应算法,首次适应算法)3)内存回收算法(考虑四种邻接情况,尤其是采用最佳(坏)适应算法时的分区合并)4)碎片拼接算法5)空闲分区队列显示6)占用分区队列显示(3)各函数调用关系(4)主要函数流程图allocateMemoByWF();//两种算法分配回收大致相同,在这里只列举一种compactMemo()freeMemoByWF()5. 源代码#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 512 //系统能分配的最大内存#define FALSE 0#define TRUE 1int type = 0; //算法类型//空闲分区struct freelink {int len; //len为分区长度int address; //address为分区起始地址struct freelink *next;};//占用分区struct busylink {char name; //作业或进程名,name='S' 表示OS占用int len;int address;struct busylink *next;};struct freelink *free_head = NULL; //自由链队列(带头结点)队首指针struct busylink *busy_head = NULL, //占用区队列队(带头结点)首指针*busy_tail = NULL; //占用区队列队尾指针//初始化void init() {struct freelink *p;struct busylink *q;free_head = (struct freelink*)malloc(sizeof(struct freelink));free_head->next = NULL; // 创建自由链头结点busy_head = busy_tail = (struct busylink*)malloc(sizeof(struct busylink));busy_head->next = NULL; // 创建占用链头结点p = (struct freelink *)malloc(sizeof(struct freelink));p->address = 64;p->len = MAX_SIZE - 64; //(OS占用了64K)p->next = NULL;free_head->next = p;q = (struct busylink *)malloc(sizeof(struct busylink));q->name = 'S'; //S表示操作系统占用q->len = 64;q->address = 0;q->next = NULL;busy_head->next = q;busy_tail = q;}//紧凑struct freelink* compactMemo(int require) {int sum = 0;struct freelink *fNode = free_head->next;while (fNode != NULL) {sum += fNode->len;fNode = fNode->next;}printf("\n");if (sum < require) {return NULL;}//删除空闲区所有节点struct freelink *p = free_head->next; //让p一直指向第一个数据节点while (p != NULL) {free_head->next = p->next;free(p);p = free_head->next;}//创建新的分区struct freelink *node = (struct freelink*)malloc(sizeof(struct freelink));node->address = 0;node->len = MAX_SIZE;free_head->next = node;node->next = NULL;//修改占用区作业内存地址struct busylink *q = busy_head->next;while (q != NULL) {q->address = node->address;node->len -= q->len;node->address += q->len;q = q->next;}return node;}//最坏(佳)适应算法在分区合并和分割后需要调整分区位置int adjust(struct freelink *node) {struct freelink *p = free_head;//合并后链表中只剩一个分区if (p->next == NULL) {free_head->next = node;node->next = NULL;return TRUE;}while (p->next != NULL && node->len <= p->next->len) { p = p->next;}if (p->next == NULL) {p->next = node;node->next = NULL;}else {node->next = p->next;p->next = node;}return TRUE;}//最坏适应算法int allocateMemoByWF() {int require;printf("请输入作业所需内存大小:");scanf("%d", &require);//判断第一个空闲分区大小是否满足需求struct freelink *p = free_head->next;if (p->len < require) {printf("没有分区满足要求,正在尝试碎片拼接...\n");//判断所有分区容量总和是否满足要求if ((p = compactMemo(require)) == NULL) {return FALSE;}}//将第一个空闲分区切割require分配给该作业struct busylink *q = (struct busylink *)malloc(sizeof(struct busylink));printf("请输入作业名称:");getchar(); //输入require之后有一个换行符,用getchar吃掉scanf("%c", &q->name);//检查是否重名struct busylink *temp = busy_head->next;while (temp != NULL && temp->name != q->name) {temp = temp->next;}if (temp != NULL) {printf("该作业名已存在!\n");return FALSE;}q->len = require;q->address = p->address;q->next = NULL;//将作业按地址递增的顺序插入到作业队列中temp = busy_head;while(temp->next != NULL && q->address > temp->next->address) { temp = temp->next;}if (temp->next == NULL) {temp->next = q;q->next = NULL;}else {q->next = temp->next;temp->next = q;}//分割空闲分区if (p->len == require) {free(p);return TRUE;}else {p->address += require;p->len -= require;}//把第一个分区从空闲区中拿出来if (p->next != NULL) {free_head->next = p->next;}else return TRUE; //空闲队列中是否只存在一个节点//将分割后的分区放到合适的位置adjust(p);return TRUE;}//首次适应算法int allocateMemoByFF() {int require;printf("请输入作业所需内存大小:");scanf("%d", &require);struct freelink *p = free_head->next;struct freelink *pre = free_head;while (p != NULL && p->len < require) {pre = p;p = p->next;}if (p == NULL) {printf("没有分区满足要求,正在尝试碎片拼接...\n");//判断所有分区容量总和是否满足要求if ((p = compactMemo(require)) == NULL) {return FALSE;}}//将第一个满足条件的分区分割合适的内存分配给作业struct busylink *q = (struct busylink *)malloc(sizeof(struct busylink));printf("请输入作业名称:");getchar(); //输入require之后有一个换行符,用getchar吃掉scanf("%c", &q->name);//检查是否重名struct busylink *temp = busy_head->next;while (temp != NULL && temp->name != q->name) {temp = temp->next;}if (temp != NULL) {printf("该作业名已存在!\n");return FALSE;}q->len = require;q->address = p->address;q->next = NULL;//将作业按地址递增的顺序插入到作业队列中temp = busy_head;while(temp->next != NULL && q->address > temp->next->address) { temp = temp->next;}if (temp->next == NULL) {temp->next = q;q->next = NULL;}else {q->next = temp->next;temp->next = q;}//分割空闲分区if (p->len == require) {pre->next = p->next;free(p);return TRUE;}else {p->address += require;p->len -= require;return TRUE;}}//匹配节点并创建回收分区struct freelink* matchName(char name) {struct busylink *q = busy_head;struct freelink *node = (struct freelink *)malloc(sizeof(struct freelink));//找到匹配节点的前一个while (q->next != NULL && q->next->name != name) {q = q->next;}if (q->next == NULL) {printf("%c进程不存在\n",name);return NULL;}//接收匹配节点的内存信息node->len = q->next->len;node->address = q->next->address;//在占用分区中删除匹配的节点struct busylink *temp = q->next;if (q->next == busy_tail) {busy_tail = q;q->next = NULL;}else {q->next = q->next->next;}free(temp);return node;}int freeMemoByWF() {printf("请输入作业名称:");char name;getchar();scanf("%c", &name);printf("\n");//将内存(即node节点)放回空闲区struct freelink *node;if ((node = matchName(name)) == NULL) {return FALSE;}struct freelink *p = free_head->next;struct freelink *pre = free_head;//三种邻接情况(合并后需要重新根据大小排序)while (p != NULL) {//与下一分区邻接if (node->address + node->len == p->address) {//与上一分区邻接if (p->next != NULL&&p->next->address + p->next->len == node->address) {struct freelink* temp = p->next;temp->len = temp->len + p->len + node->len;free(node);pre->next = temp->next;free(p);adjust(temp);printf("回收成功!\n");return TRUE;}else {p->address = node->address;p->len += node->len;free(node);pre->next = p->next; //把合并后分区取出来adjust(p);printf("回收成功!\n");return TRUE;}}//与上一分区邻接if (p->address + p->len == node->address) {//同时与下一分区邻接if (p->next != NULL &&node->address + node->len == p->next->address) {p->len = p->len + node->len + p->next->len;pre->next = p->next->next;free(p->next);free(node);adjust(p);printf("回收成功!\n");return TRUE;}else {p->len += node->len;free(node);pre->next = p->next;adjust(p);printf("回收成功!\n");return TRUE;}}pre = p;p = p->next;}//不邻接adjust(node);printf("回收成功!\n");return TRUE;}int freeMemoByFF() {printf("请输入作业名称:");char name;getchar();scanf("%c", &name);printf("\n");//将内存(node节点)放回空闲区struct freelink *node;if ((node = matchName(name)) == FALSE) {return FALSE;}struct freelink *p = free_head->next;//三种邻接情况while (p != NULL) {//与下一分区邻接if (node->address + node->len == p->address) {p->address = node->address;p->len += node->len;free(node);printf("回收成功!\n");return TRUE;}//与上一分区邻接if (p->address + p->len == node->address) {//同时与下一分区邻接if (p->next != NULL &&node->address + node->len == p->next->address) {p->len = p->len + node->len + p->next->len;struct freelink* temp = p->next;p->next = p->next->next;free(temp);free(node);printf("回收成功!\n");return TRUE;}else {p->len += node->len;free(node);printf("回收成功!\n");return TRUE;}}p = p->next;}//不邻接p = free_head;while (p->next != NULL && node->address > p->next->address) { p = p->next;}if (p->next == NULL) {p->next = node;node->next = NULL;}/*回收分区是分区链中地址最大的一个*/else {node->next = p->next;p->next = node;}printf("回收成功!\n");return TRUE;}//输出空闲分区void printFreeLink() {struct freelink *p = free_head->next;printf("空闲分区:\n");while (p != NULL) {printf("分区起始地址:%d ", p->address);printf("分区大小:%d\n", p->len);p = p->next;}printf("\n");}//输出占用分区void printBusyLink() {struct busylink *q = busy_head->next;printf("占用分区:\n");while (q != NULL) {printf("进程名:%c ", q->name);printf("起始地址:%d ", q->address);printf("占用内存大小:%d\n", q->len);q = q->next;}printf("\n");}void WF() {while(1) {printf("----------------------------------------------------------------\n");printf("1. 初始化\n\n");printf("2. 作业进入内存\n\n");printf("3. 作业完成\n\n");printf("4. 显示当前自由分区\n\n");printf("5. 显示当前作业占用分区\n\n");printf("6. 退出\n");printf("----------------------------------------------------------------\n");int m;scanf("%d", &m);printf("\n");switch(m) {case 1: init(); break;case 2: allocateMemoByWF(); break;case 3: freeMemoByWF(); break;case 4: printFreeLink(); break;case 5: printBusyLink(); break;case 6: return;}}}void FF() {while(1) {printf("----------------------------------------------------------------\n");printf("1. 初始化\n\n");printf("2. 作业进入内存\n\n");printf("3. 作业完成\n\n");printf("4. 显示当前自由分区\n\n");printf("5. 显示当前作业占用分区\n\n");printf("6. 退出\n");printf("----------------------------------------------------------------\n");int m;scanf("%d", &m);printf("\n");switch(m) {case 1: init(); break;case 2: allocateMemoByFF(); break;case 3: freeMemoByFF(); break;case 4: printFreeLink(); break;case 5: printBusyLink(); break;case 6: return;}}}int main() {while(1) {printf("----------------------------------------------------------------\n");printf("1. 首次适应算法\n\n");printf("2. 最坏适应算法\n\n");printf("3. 退出\n");printf("----------------------------------------------------------------\n");int m;scanf("%d", &m);printf("\n");switch(m) {case 1: FF(); break;case 2: WF(); break;case 3: exit(0);}}}6. 实验结果:1.最坏适应算法:A(16), B(32), C(64), D(128)分配(成功):分配失败(重名):当前空闲区和占用区情况:free(A)//不邻接回收成功:回收失败(不存在该进程):当前空闲区和占用区情况:free(C)当前空闲区情况:free(B)//与上下分区邻接当前空闲区情况:E(100)当前空闲区情况:F(200)没有分区满足时尝试碎片拼接当前空闲区和占用区情况:最坏适应算法有一种情况:A(40), B(50), C(60), D(50)free(A), free(C)与首次适应分配不同,最坏适应算法可能高地址在低地址前free(B)2. 首次适应算法:A(16), B(32), C(64), D(128),E(10),F(5),free(F)free(A), free(C)free(B)G(200)在分配内存过程中,将作业加入到占用队列时是按地址递增的顺序排列,保证了拼凑算法后各作业的相对位置不变化7. 实验总结:a)以前对链表操作有一些误操作,比如排序时,一般使用冒泡法。

实验2可变分区管理及存储管理

实验2可变分区管理及存储管理

实验2 可变分区管理一、存储管理背景知识1. 分页过程2. 内存共享3. 未分页合并内存与分页合并内存4. 提高分页性能耗尽内存是Windows系统中最常见的问题之一。

当系统耗尽内存时,所有进程对内存的总需求超出了系统的物理内存总量。

随后,Windows必须借助它的虚拟内存来维持系统和进程的运行。

虚拟内存机制是Windows操作系统的重要组成部分,但它的速度比物理内存慢得多,因此,应该尽量避免耗尽物理内存资源,以免导致性能下降。

解决内存不足问题的一个有效的方法就是添加更多的内存。

但是,一旦提供了更多的内存,Windows很可以会立即“吞食”。

而事实上,添加更多的内存并非总是可行的,也可能只是推迟了实际问题的发生。

因此,应该相信,优化所拥有的内存是非常关键的。

1. 分页过程当Windows求助于硬盘以获得虚拟内存时,这个过程被称为分页(paging) 。

分页就是将信息从主内存移动到磁盘进行临时存储的过程。

应用程序将物理内存和虚拟内存视为一个独立的实体,甚至不知道Windows使用了两种内存方案,而认为系统拥有比实际内存更多的内存。

例如,系统的内存数量可能只有16MB,但每一个应用程序仍然认为有4GB内存可供使用。

使用分页方案带来了很多好处,不过这是有代价的。

当进程需要已经交换到硬盘上的代码或数据时,系统要将数据送回物理内存,并在必要时将其他信息传输到硬盘上,而硬盘与物理内存在性能上的差异极大。

例如,硬盘的访问时间通常大约为4-10毫秒,而物理内存的访问时间为60 us,甚至更快。

2. 内存共享应用程序经常需要彼此通信和共享信息。

为了提供这种能力,Windows必须允许访问某些内存空间而不危及它和其他应用程序的安全性和完整性。

从性能的角度来看,共享内存的能力大大减少了应用程序使用的内存数量。

运行一个应用程序的多个副本时,每一个实例都可以使用相同的代码和数据,这意味着不必维护所加载应用程序代码的单独副本并使用相同的内存资源。

模拟实现一个简单的可变分区存储管理系统资料

模拟实现一个简单的可变分区存储管理系统资料

合肥学院计算机科学与技术系实验报告2013 ~2014 学年第一学期课程操作系统原理实验名称模拟实现一个简单的可变分区存储管理系统学生姓名专业班级指导教师谢雪胜2013 年12 月1.实验目的模拟实现一个简单的固定(或可变)分区存储管理系统2.实验内容本实验要求完成如下任务:(1)建立相关的数据结构,作业控制块、已分配分区及未分配分区(2)实现一个分区分配算法,如最先适应分配算法、最优或最坏适应分配算法(3)实现一个分区回收算法(4)给定一批作业/进程,选择一个分配或回收算法,实现分区存储的模拟管理。

3.实验步骤(1)任务分析本实验要实现的功能是模拟分区管理系统,即输入一个批作业,由程序根据各个作业的大小为批作业分配分区。

如果能找到满足条件的分区,则分配成功,否则分配失败。

对于程序的输入,输入用户程序所要请求的分区大小,-1表示输入完成。

程序输入分配分区后各个分区的使用情况,然后回收分区,程序输出回收分区后各个分区的使用情况。

(2)概要设计对于分区的定义,定义的数据结构如下所示typedef struct{int no; //定义分区编号int size; //定义大小int start; //定义分区起始位置int state; //定义分区状态,已分配或未分配}fenqubiao;fenqubiao arr[50];其中,no表示分区的编号,size表示当前分区块的大小,start表示当前分区的起始位置,state表示当前分区的状态,已分配或空闲。

Arr[50]表示当前系统所有分区情况。

主程序的流程图如下:开始初始化分区输出分区表输入分区请求N 是否输入完Y输出分区表输入回收分区编号N 是否输入完Y结束(3)详细设计一、初始化分区Fenqubiao arr[50]={{1,10,0,0},{2,20,10,1},{3,10,30,0},{4,12,40,0},{5,30,52,1},{6,25,82,0},{7,20,107,0},{8,5,127,1},{9,64,132,0},{10,32,196,0}};二、分区分配函数采用的分区分配函数是最先适应法,每次从地址部分开始遍历。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

合肥学院计算机科学与技术系实验报告2013 ~2014 学年第一学期课程操作系统原理实验名称模拟实现一个简单的可变分区存储管理系统学生姓名专业班级指导教师谢雪胜2013 年12 月1.实验目的模拟实现一个简单的固定(或可变)分区存储管理系统2.实验内容本实验要求完成如下任务:(1)建立相关的数据结构,作业控制块、已分配分区及未分配分区(2)实现一个分区分配算法,如最先适应分配算法、最优或最坏适应分配算法(3)实现一个分区回收算法(4)给定一批作业/进程,选择一个分配或回收算法,实现分区存储的模拟管理。

3.实验步骤(1)任务分析本实验要实现的功能是模拟分区管理系统,即输入一个批作业,由程序根据各个作业的大小为批作业分配分区。

如果能找到满足条件的分区,则分配成功,否则分配失败。

对于程序的输入,输入用户程序所要请求的分区大小,-1表示输入完成。

程序输入分配分区后各个分区的使用情况,然后回收分区,程序输出回收分区后各个分区的使用情况。

(2)概要设计对于分区的定义,定义的数据结构如下所示typedef struct{int no; //定义分区编号int size; //定义大小int start; //定义分区起始位置int state; //定义分区状态,已分配或未分配}fenqubiao;fenqubiao arr[50];其中,no表示分区的编号,size表示当前分区块的大小,start表示当前分区的起始位置,state表示当前分区的状态,已分配或空闲。

Arr[50]表示当前系统所有分区情况。

主程序的流程图如下:(3)详细设计一、初始化分区Fenqubiao arr[50]={{1,10,0,0},{2,20,10,1},{3,10,30,0},{4,12,40,0},{5,30,52,1},{6,25,82,0},{7,20,107,0},{8,5,127,1},{9,64,132,0},{10,32,196,0}};二、分区分配函数采用的分区分配函数是最先适应法,每次从地址部分开始遍历。

本程序用的是编号作为遍历的关键字,方便处理。

如果当前分区的大小大于所请求的大小,并且分区处于空闲状态,则进行分区,划出满足请求大小的分区,并修改状态为已分配。

如果所划分分区所剩空间不为0,则修改其首址,设定其大小,添加到分区表中。

如果当前分区不满足请求,则继续查找,直至所有分区遍历完成。

然后返回分配失败给请求者。

具体代码如下:int fun_allocate(int x,int *num,fenqubiao *arr){int i=0,p;fenqubiao t={0,0,0,0};for(i=0;i<*num;i++){if(arr[i].size>=x && arr[i].state==0) break;0 10 30 40 52 82 107 127 132 196 228if(i==*num)return 0;p=i;t.no=arr[i].no+1;t.size=arr[i].size-x;t.start=arr[i].start+x;t.state=0;arr[i].size=x;arr[i].state=1;if(t.size!=0){for(i=*num;i>p;i--){arr[i]=arr[i-1];arr[i].no=arr[i].no+1;}arr[p+1]=t;*num=*num+1;}return *num;}三、输出分区使用情况对分区表进行遍历,输出各个分区的信息(编号,大小,起始,状态)。

其中为了简单易懂,若状态为0则输出空闲,否则输出已分配。

void fun_print(fenqubiao *arr,int num){int i=0;printf("编号大小起始状态\n");for(i=0;i<num;i++)printf("%2d%7d%7d",arr[i].no,arr[i].size,arr[i].start);if(arr[i].state==1)printf(" 已分配\n");elseprintf(" 空闲\n");}}四、回收分区对所要回收的分区,则有四种情况。

1、上临空闲,下临空闲:修改上一个分区大小为三个分区大小之和,下临区之后的分区改变其分区编号,往前移两个。

2、上临空闲:修改上一个分区大小为两个分区大小之和,下临区之后的分区上移一个单位。

3、下临空闲:修改当前分区大小为两个分区大小之和,修改状态为未分配。

然后下临区之后的分区上移一个单位。

4、上下均无空闲:直接修改状态为未分配。

如果具体代码如下:void fun_huishou(int no,int *num,fenqubiao *arr){int i=0;int p=0;for(i=1;i<=*num;i++){if(arr[i].no==no){p=i;break;}}if(arr[p-1].state==0 && arr[p+1].state==0)//上下临区arr[p-1].size=arr[p-1].size+arr[p].size+arr[p+1].size;for(i=p;i<*num-1;i++){arr[i]=arr[i+2];arr[i].no=arr[i].no-2;}*num=*num-2;}else if(arr[p+1].state==0)//下临区{arr[p].size=arr[p].size+arr[p+1].size;arr[p].state=0;for(i=p+1;i<*num;i++){arr[i]=arr[i+1];arr[i].no=arr[i].no-1;}*num=*num-1;}else if(arr[p-1].state==0) //上临区{arr[p-1].size=arr[p-1].size+arr[p].size;for(i=p;i<*num;i++){arr[i]=arr[i+1];arr[i].no=arr[i].no-1;}*num=*num-1;}else //无相邻分区{arr[p].state=0;}}(4)调试分析实验结果截图如下:4.实验总结首次适应算法,分配时,当进程申请大小为SIZE的内存时,系统从空闲区表的第一个表目开始查询,直到首次找到等于或大于SIZE的空闲区。

从该区中划出大小为SIZE的分区分配给进程,余下的部分仍作为一个空闲区留在空闲区表中,但要修改其首址和大小。

回收时,按释放区的首址,查询空闲区表,若有与释放区相邻的空闲区,则合并到相邻的空闲区中,并修改该区的大小和首址,否则,把释放区作为一个空闲区,将其大小和首址按照首地址大小递增的顺序插入到空闲区表的适当位置。

这里,采用数组的方式,模拟内存分配首次适应算法,动态的为作业分配内存块。

可以根据作业名称回收已分配的内存块,当空闲内存块相邻时,则合并,不相邻是,直接插入。

通过此次的实验,让我对内存分配中首次适应算法更加熟悉,还通过这次实验了解了分配空间的另外两种方法:最佳和最坏算法。

通过编程模拟实现操作系统的可变分区存储管理的功能,一方面加深对原理的理解,另一方面提高根据已有原理通过编程解决实际问题的能力,为进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。

5.附录程序源代码#include <stdio.h>typedef struct{int no; //定义分区编号int size; //定义大小int start; //定义分区起始位置int state; //定义分区状态,已分配或未分配}fenqubiao;int fun_allocate(int x,int *num,fenqubiao *arr);//分区算法,分配成功返回分区数,否则返回0void fun_print(fenqubiao *arr,int num); //输出当前分区表状态void fun_huishou(int no,int *num,fenqubiao *arr);int main(){fenqubiaoarr[50]={{1,10,0,0},{2,20,10,1},{3,10,30,0},{4,12,40,0},{5,30,52,1}, {6,25,82,0},{7,20,107,0},{8,5,127,1},{9,64,132,0},{10,32,196,0}};int num=10; //用于统计分区个数int i=0,x,t;puts("||====================操作系统大实验==================||");puts("|| ||");puts("|| 题目:模拟实现一个可变分区存储管理系统 ||");puts("|| ||");puts("|| ||");puts("|| 制作者信息: ||");puts("|| ||");puts("|| 姓名学号 ||");puts("|| 万定国 1104032034 ||");puts("|| 刘国庆 1104032035 ||");puts("|| 许成谦 1104032036 ||");puts("|| 祁益祥 1104032037 ||");puts("|| 朱旭 1104032038 ||");puts("|| ||");puts("||====================================================||");system("pause");system("cls");printf("初始分区情况:\n");printf("编号大小起始状态\n");for(i=0;i<10;i++){printf("%2d%7d%7d",arr[i].no,arr[i].size,arr[i].start);if(arr[i].state==1)printf(" 已分配\n");elseprintf(" 空闲\n");}printf("====请求资源====\n");printf("输入请求大小(-1结束):\n");while(scanf("%d",&x) && x!=-1){t=fun_allocate(x,&num,arr);if(t==0)printf("分配失败!\n");else{num=t;fun_print(arr,num);}}printf("====回收资源=====\n");printf("请输入回收分区的编号(-1结束):\n");while(scanf("%d",&x) && x!=-1){fun_huishou(x,&num,arr);fun_print(arr,num);}}int fun_allocate(int x,int *num,fenqubiao *arr) {int i=0,p;fenqubiao t={0,0,0,0};for(i=0;i<*num;i++){if(arr[i].size>=x && arr[i].state==0)break;}if(i==*num)return 0;p=i;t.no=arr[i].no+1;t.size=arr[i].size-x;t.start=arr[i].start+x;t.state=0;arr[i].size=x;arr[i].state=1;if(t.size!=0){for(i=*num;i>p;i--){arr[i]=arr[i-1];arr[i].no=arr[i].no+1;}arr[p+1]=t;*num=*num+1;}return *num;}void fun_print(fenqubiao *arr,int num){int i=0;printf("编号大小起始状态\n");for(i=0;i<num;i++){printf("%2d%7d%7d",arr[i].no,arr[i].size,arr[i].start);if(arr[i].state==1)printf(" 已分配\n");elseprintf(" 空闲\n");}}void fun_huishou(int no,int *num,fenqubiao *arr){int i=0;int p=0;for(i=1;i<=*num;i++){if(arr[i].no==no){p=i;break;}}if(arr[p-1].state==0 && arr[p+1].state==0)//上下临区{arr[p-1].size=arr[p-1].size+arr[p].size+arr[p+1].size;for(i=p;i<*num-1;i++){arr[i]=arr[i+2];arr[i].no=arr[i].no-2;}*num=*num-2;}else if(arr[p+1].state==0)//下临区{arr[p].size=arr[p].size+arr[p+1].size;arr[p].state=0;for(i=p+1;i<*num;i++){arr[i]=arr[i+1];arr[i].no=arr[i].no-1;}*num=*num-1;}else if(arr[p-1].state==0) //上临区{arr[p-1].size=arr[p-1].size+arr[p].size;for(i=p;i<*num;i++){arr[i]=arr[i+1];arr[i].no=arr[i].no-1;}*num=*num-1;}else //无相邻分区{arr[p].state=0;}}。

相关文档
最新文档