操作系统实验动态分区分配算法
实验报告-动态分区分配算法
南昌大学实验报告学生姓名:马江涛学号:8000612091 专业班级:计算机软件121班实验类型:□验证□综合□设计□创新实验日期:2014-05-08 实验成绩:【实验要求】1、编程实现首次适应算法和最佳适应算法的动态分区分配的分配过程和回收过程。
其中,空闲分区通过分区链来管理;在进行内存分配时,系统优先使用空闲区低端的空间。
2、假设初始状态下,可用内存空间为640K,并依次有下列请求序列:1)作业1申请130KB。
2)作业2申请60KB。
3)作业3申请100KB。
4)作业2释放60KB。
5)作业4申请200KB。
6)作业3释放100KB。
7)作业1释放130KB。
8)作业5申请140KB。
9)作业6申请60KB。
10)作业7申请50KB。
11)作业6释放60KB。
请分别用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况【可参考后文的实验提示】。
3、上机时认真的进行测试,输入不同的资源分配请求,写出实验结果;4、具体要求:(1)对你的程序关键代码处进行注释。
(2)给出实验数据,对结果进行分析,说明对相关知识点的理解。
【实验目的】了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
【实验思路】首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。
只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;如果该空闲空间与所需空间大小一样,则从空闲表中取消该项;如果还有剩余,则余下的部分仍留在空闲表中,但应修改分区大小和分区始址。
最佳适应算法(Best-fit):当要分配内存空间时,就查找空闲表中满足要求的空闲块,并使得剩余块是最小的。
然后把它分配出去,若大小恰好合适,则直按分配;若有剩余块,则仍保留该余下的空闲分区,并修改分区大小的起始地址。
内存回收:将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。
动态分区分配方式的模拟实验原理说明
动态分区分配方式的模拟实验原理说明一、引言动态分区分配方式是操作系统中的一种内存管理方式,它将内存分为若干个不同大小的分区,根据进程的需求动态地分配内存。
在实际应用中,动态分区分配方式广泛应用于多任务操作系统中,如Windows、Linux等。
本文将介绍动态分区分配方式的模拟实验原理。
二、动态分区分配方式的基本原理动态分区分配方式是指在内存空间中按照进程需要划分出若干个不同大小的空间块,每个空间块可以被一个进程占用。
当有新进程需要内存时,操作系统会在空闲的空间块中选择一个大小合适的空间块给该进程使用。
当进程结束时,该进程所占用的空间块就会被释放出来,成为空闲块。
三、模拟实验环境搭建为了模拟动态分区分配方式,我们需要搭建一个虚拟机环境。
首先需要安装一款虚拟机软件(如VMware Workstation),然后安装一个操作系统(如Windows)。
接下来,在虚拟机中安装Visual Studio等开发工具。
四、模拟实验步骤1.设计数据结构为了方便管理内存空间,我们需要设计一种数据结构来存储内存块的信息。
我们可以使用链表来实现这一功能,每个节点表示一个内存块,包括该内存块的起始地址、大小以及状态(已分配或未分配)等信息。
2.初始化内存空间在模拟实验中,我们需要初始化一段虚拟内存空间。
我们可以使用一个数组来表示整个内存空间,并将其划分为若干个大小不同的空间块。
同时,我们需要将这些空间块的信息存储到链表中。
3.模拟进程请求内存在模拟实验中,我们需要模拟多个进程同时请求内存的情况。
当一个进程请求内存时,操作系统会根据其所需的内存大小,在空闲的空间块中选择一个合适的块分配给该进程,并将该块标记为已分配状态。
4.模拟进程释放内存当一个进程结束时,它所占用的内存块就会被释放出来,成为空闲块。
此时操作系统会更新链表信息,并将该块标记为未分配状态。
5.显示当前内存使用情况在模拟实验过程中,我们需要不断地显示当前的内存使用情况。
实验四动态分区分配算法
实验容:存储器管理实验一、实验目的采用首次适应算法〔FF〕,最正确适应算法〔BF〕,最坏适应算法〔WF〕三种不同的算法,实现对系统空闲区的动态分区分配。
二、实验题目给予顺序搜索的动态分区算法的程序。
三、实验要求读懂给出的核心代码,进展适当的修改,编译通过后,完成实验报告。
四、核心代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>//常量定义#define PROCESS_NAME_LEN 32#define MIN_SLICE 10#define DEFAULT_MEM_SIZE 1024#define DEFAULT_MEM_START 0#define MA_FF 1#define MA_BF 2#define MA_WF 3int mem_size=DEFAULT_MEM_SIZE;int ma_algorithm = MA_FF;static int pid = 0;int flag = 0;struct free_block_type{int size;int start_addr;struct free_block_type *next;};struct free_block_type *free_block;//描述已分配的存块struct allocated_block{int pid; int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};struct allocated_block *allocated_block_head = NULL;//函数声明struct free_block_type* init_free_block(int mem_size);void display_menu();int set_mem_size();void set_algorithm();void rearrange(int algorithm);int rearrange_FF();int rearrange_BF();int rearrange_WF();int new_process();int allocate_mem(struct allocated_block *ab);void kill_process();int free_mem(struct allocated_block *ab);int dispose(struct allocated_block *free_ab);int display_mem_usage();void do_exit();struct allocated_block *find_process(int pid);int main(){char choice; pid=0;free_block= init_free_block(mem_size); //初始化空闲区while(1) {display_menu(); //显示菜单fflush(stdin);choice=getchar(); //获取用户输入switch(choice){case '1': set_mem_size(); break; //设置存大小case '2': set_algorithm();flag=1; break;//设置算法case '3': new_process(); flag=1; break;//创立新进程case '4': kill_process(); flag=1; break;//删除进程case '5': display_mem_usage(); flag=1; break; //显示存使用case '0': do_exit(); exit(0); //释放链表并退出default: break;}}return 1;}struct free_block_type* init_free_block(int mem_size){struct free_block_type *fb;fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(fb==NULL){printf("No mem\n");return NULL;}fb->size = mem_size;fb->start_addr = DEFAULT_MEM_START;fb->next = NULL;return fb;}void display_menu(){printf("\n");printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);printf("2 - Select memory allocation algorithm\n");printf("3 - New process \n");printf("4 - T erminate a process \n");printf("5 - Display memory usage \n");printf("0 - Exit\n");}int set_mem_size(){int size;if(flag!=0){ //防止重复设置printf("Cannot set memory size again\n");return 0;}printf("T otal memory size =");scanf("%d", &size);if(size>0) {mem_size = size;free_block->size = mem_size;}flag=1;return 1;}void set_algorithm(){int algorithm;while(1) {printf("\t1 - First Fit\n");printf("\t2 - Best Fit \n");printf("\t3 - Worst Fit \n");scanf("%d", &algorithm);if(algorithm>=1 && algorithm <=3) {ma_algorithm = algorithm;break;}elseprintf("输入有误,请重新输入!\n");}//按指定算法重新排列空闲区链表rearrange(ma_algorithm);}void rearrange(int algorithm){switch(algorithm){case MA_FF: rearrange_FF(); break;case MA_BF: rearrange_BF(); break;case MA_WF: rearrange_WF(); break;}}//首次适应算法int rearrange_FF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小地址的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小地址int min_addr = free_block->start_addr;temp = free_block;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_addr = thead->next->start_addr;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最正确适应算法int rearrange_BF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小存int min_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最坏适应算法int rearrange_WF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最大存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最大存int max_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {max_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}int new_process(){struct allocated_block *ab;int size;int ret;ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));if(!ab) exit(-5);ab->next = NULL;pid++;sprintf(ab->process_name, "PROCESS-d", pid);ab->pid = pid;while(1) {printf("Memory for %s:", ab->process_name);scanf("%d", &size);if(size>0) {ab->size=size;break;}else printf("输入大小有误,请重新输入\n");}ret = allocate_mem(ab);if((ret==1) &&(allocated_block_head == NULL)){allocated_block_head=ab;return 1;}else if (ret==1) {ab->next = allocated_block_head;allocated_block_head = ab;return 2; }else if(ret==-1){printf("Allocation fail\n");pid--;free(ab);return -1;}return 3;}int allocate_mem(struct allocated_block *ab){struct free_block_type *fbt, *pre,*head,*temp,*tt;struct allocated_block *tp;int request_size=ab->size;int sum=0;int max;head = (struct free_block_type *)malloc(sizeof(struct free_block_type));pre = head;fbt = free_block;pre->next = fbt;if(ma_algorithm==MA_WF) {if(NULL==fbt||fbt->size<request_size)return -1;}else {while(NULL!=fbt&&fbt->size<request_size) {pre = fbt;fbt = fbt->next;}}if(NULL==fbt||fbt->size<request_size) {if(NULL!=free_block->next) {sum = free_block->size;temp = free_block->next;while(NULL!=temp) {sum += temp->size;if(sum>=request_size)break;temp = temp->next;}if(NULL==temp)return -1;else {pre = free_block;max = free_block->start_addr;fbt = free_block;while(temp->next!=pre) {if(max<pre->start_addr) {max = pre->start_addr;fbt = pre;}pre = pre->next;}pre = free_block;while(temp->next!=pre) {tp = allocated_block_head;tt = free_block;if(pre!=fbt) {while(NULL!=tp) {if(tp->start_addr>pre->start_addr)tp->start_addr = tp->start_addr - pre->size;tp = tp->next;}while(NULL!=tt) {if(tt->start_addr>pre->start_addr)tt->start_addr = tt->start_addr - pre->size;tt = tt->next;}}pre = pre->next;}pre = free_block;while(pre!=temp->next) {if(pre!=fbt)free(pre);pre = pre->next;}free_block = fbt;free_block->size = sum;free_block->next = temp->next;if(free_block->size - request_size < MIN_SLICE) {ab->size = free_block->size;ab->start_addr = free_block->start_addr;pre = free_block;free_block = free_block->next;free(pre);}else {ab->start_addr = fbt->start_addr;free_block->start_addr = free_block->start_addr + request_size;free_block->size = free_block->size - request_size;}}}elsereturn -1;}else {//将存块全局部配if(fbt->size - request_size < MIN_SLICE) {ab->size = fbt->size;ab->start_addr = fbt->start_addr;if(pre->next==free_block) {free_block = fbt->next;}elsepre->next = fbt->next;free(fbt);}else {ab->start_addr = fbt->start_addr;fbt->start_addr = fbt->start_addr + request_size;fbt->size = fbt->size - request_size;}}free(head);rearrange(ma_algorithm);return 1;}void kill_process(){struct allocated_block *ab;int pid;printf("Kill Process, pid=");scanf("%d", &pid);ab = find_process(pid);if(ab!=NULL){free_mem(ab);dispose(ab);}else {printf("没有pid为%d的进程!\n",pid);}}struct allocated_block *find_process(int pid) {struct allocated_block *ab=NULL;ab = allocated_block_head;while(NULL!=ab&&ab->pid!=pid)ab = ab->next;return ab;}int free_mem(struct allocated_block *ab){int algorithm = ma_algorithm;struct free_block_type *fbt, *pre=NULL,*head;fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));pre=(struct free_block_type*) malloc(sizeof(struct free_block_type));if(!fbt) return -1;// 进展可能的合并,根本策略如下// 1. 将新释放的结点插入到空闲分区队列末尾// 2. 对空闲链表按照地址有序排列// 3. 检查并合并相邻的空闲分区// 4. 将空闲链表重新按照当前算法排序head = pre;fbt->start_addr = ab->start_addr;fbt->size = ab->size;fbt->next = free_block; //新释放的结点插入到空闲分区链表的表头free_block = fbt;rearrange_FF(); //对空闲链表按照地址有序排列pre->next = free_block; //求的pre为fbt的前一个结点pre->size = 0;while(pre->next->start_addr!=fbt->start_addr)pre = pre->next;//左右分区都存在if(0!=pre->size&&NULL!=fbt->next) {//左右分区都可合并if((pre->start_addr+pre->size)==fbt->start_addr && (fbt->start_addr+fbt->size)==fbt->next->start_addr) {pre->size = pre->size + fbt->size + fbt->next->size;pre->next = fbt->next->next;free(fbt->next);free(fbt);}//左分区可合并else if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}//右分区可合并else if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//左分区不存在else if(0==pre->size) {if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//右分区不存在else if(NULL==fbt->next) {if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}}rearrange(algorithm);free(head);return 1;}int dispose(struct allocated_block *free_ab){struct allocated_block *pre, *ab;if(free_ab == allocated_block_head) {allocated_block_head = allocated_block_head->next;free(free_ab);return 1;}pre = allocated_block_head;ab = allocated_block_head->next;while(ab!=free_ab){ pre = ab; ab = ab->next; }pre->next = ab->next;free(ab);return 2;}int display_mem_usage(){struct free_block_type *fbt=free_block;struct allocated_block *ab=allocated_block_head;if(fbt==NULL) return(-1);printf("----------------------------------------------------------\n");printf("Free Memory:\n");printf(" s s\n", " start_addr", " size");while(fbt!=NULL){printf(" d d\n", fbt->start_addr, fbt->size);fbt=fbt->next;}printf("\nUsed Memory:\n");printf("s s s s\n", "PID", "ProcessName", "start_addr", " size");while(ab!=NULL){printf("d s d d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);ab=ab->next;}printf("----------------------------------------------------------\n");return 0;}void do_exit() {}。
动态分区算法实验报告
动态分区算法实验报告动态分区算法实验报告一、引言计算机操作系统是现代计算机系统中的核心组成部分,它负责管理计算机硬件资源,并提供各种服务。
内存管理是操作系统的重要功能之一,它负责管理计算机的内存资源,为进程提供运行环境。
在内存管理中,动态分区算法是一种常用的内存分配策略。
本实验旨在通过实践,深入了解动态分区算法的原理和实现。
二、实验目的1. 了解动态分区算法的基本原理和实现方式;2. 掌握动态分区算法的实验环境搭建和使用方法;3. 分析动态分区算法的优缺点,并比较不同算法的性能差异。
三、实验环境本实验使用C语言编程实现,实验环境如下:1. 操作系统:Windows 10;2. 开发工具:Visual Studio 2019;3. 编程语言:C语言。
四、实验过程1. 实验准备在开始实验之前,我们首先需要了解动态分区算法的基本原理。
动态分区算法根据进程的内存需求,将内存划分为若干个不同大小的分区,并按照进程的请求进行分配和释放。
常用的动态分区算法有首次适应算法、最佳适应算法和最坏适应算法等。
2. 实验设计本实验选择实现首次适应算法,并设计以下几个函数:- 初始化内存空间:初始化一块指定大小的内存空间,将其划分为一个个的分区,并设置分区的状态;- 分配内存:根据进程的内存需求,在内存空间中找到合适的分区进行分配,并更新分区的状态;- 释放内存:将已分配的内存空间进行释放,并更新分区的状态;- 显示内存状态:打印当前内存空间的分区状态。
3. 实验实现根据上述设计,我们使用C语言实现了动态分区算法的相关函数。
通过调用这些函数,我们可以模拟动态分区算法的运行过程,并观察分区的分配和释放情况。
4. 实验结果经过实验,我们得到了以下结果:- 动态分区算法可以有效地管理内存资源,根据进程的需求进行灵活的内存分配;- 首次适应算法在内存分配效率和速度方面表现良好,但可能会导致内存碎片的产生;- 释放内存时,及时合并相邻的空闲分区可以减少内存碎片的数量。
操作系统-动态分区分配算法实验报告
实验题目:存储器内存分配设计思路:1.既然是要对内存进行操作,首先对和内存相关的内容进行设置我使用的是用自定义的数据结构struct来存放内存中一个内存块的内容包括:始地址、大小、状态(f:空闲u:使用e:结束)之后采用数组来存放自定义的数据类型,这样前期的准备工作就完成了2.有了要加工的数据,接下来定义并实现了存放自定义数据类型的数组的初始化函数和显示函数,需要显示的是每个内存块的块号、始地址、大小、状态3.接着依此定义三种动态分区分配算法首次适应算法、最佳适应算法和最差适应算法4.对定义的三种算法逐一进行实现①首次适应算法:通过遍历存放自定义数据类型的数组,找到遍历过程中第一个满足分配大小的内存块块号i,找到之后停止对数组的遍历,将i之后的块号逐个向后移动一个,然后将满足分配大小的内存块i分为两块,分别是第i块和第i+1块,将两块的始地址、大小、状态分别更新,这样便实现了首次适应算法②最佳适应算法:和首次适应算法一样,首先遍历存放自定义数据类型的数组,找到满足分配大小的内存块后,对内存块的大小进行缓存,因为最佳适应是要找到最接近要分配内存块大小的块,所以需要遍历整个数组,进而找到满足分配大小要求的而且碎片最小的块i,之后的操作和首次遍历算法相同③最差适应算法:和最佳适应算法一样,区别在于,最佳适应是找到最接近要分配内存块大小的块,而最差适应是要找到在数组中,内存最大的块i,找到之后的操作和最佳适应算法相同,因此不在这里赘述。
5.定义并实现释放内存的函数通过块号找到要释放的内存块,把要释放的内存块状态设置成为空闲,查看要释放的块的左右两侧块的状态是否为空闲,如果有空闲,则将空闲的块和要释放的块进行合并(通过改变块的始地址、大小、状态的方式)6.定义主函数,用switch来区分用户需要的操作,分别是:①首次适应②最佳适应③最差适应④释放内存⑤显示内存⑥退出系统实验源程序加注释:#include<bits/stdc++.h>#define MI_SIZE 100 //内存大小100typedef struct MemoryInfomation//一个内存块{int start; //始地址int Size; //大小char status; //状态 f:空闲 u:使用 e:结束} MI;MI MList[MI_SIZE];void InitMList() //初始化{int i;MI temp = { 0,0,'e' };for (i = 0; i < MI_SIZE; i++){MList[i] = temp;}MList[0].start = 0; //起始为0MList[0].Size = MI_SIZE;//大小起始最大MList[0].status = 'f'; //状态起始空闲}void Display() //显示{int i, used = 0;printf("\n---------------------------------------------------\n");printf("%5s%15s%15s%15s", "块号", "始地址", "大小", "状态");printf("\n---------------------------------------------------\n");for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].status == 'u'){used += MList[i].Size;}printf("%5d%15d%15d%15s\n", i, MList[i].start, MList[i].Size, MList[i].status == 'u' ? "使用" : "空闲");}printf("\n----------------------------------------------\n");}void FirstFit(){int i, j, flag = 0;int request;printf("最先适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f') {if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request; MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';flag = 1;}break;}}if (flag != 1 || i == MI_SIZE || MList[i].status == 'e'){printf("没有足够大小的空间分配\n");}Display();}void BadFit(){int i, j = 0, k = 0, flag = 0, request;printf("最坏适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0;i < MI_SIZE - 1 && MList[i].status != 'e';i++){if (MList[i].Size >= request && MList[i].status == 'f') {flag = 1;if (MList[i].Size > k){k = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2;j > i;j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}void M_Release() //释放内存{int i, number;printf("\n请问你要释放哪一块内存:\n");scanf("%d", &number);if (MList[number].status == 'u'){MList[number].status = 'f';if (MList[number + 1].status == 'f')//右边空则合并{MList[number].Size += MList[number].Size;for (i = number + 1; i < MI_SIZE - 1 && MList[i].status != 'e'; i++) { //i后面的每一个结点整体后移if (i > 0){MList[i] = MList[i + 1];}}}if (number > 0 && MList[number - 1].status == 'f')//左边空则合并{MList[number - 1].Size += MList[number].Size;for (i = number; i < MI_SIZE - 1 && MList[i].status != 'e'; i++){MList[i] = MList[i + 1];}}}else{printf("该块内存无法正常释放\n");}Display();}void BestFit(){int i, j = 0, t, flag = 0, request;printf("最佳适应算法:请问你要分配多大的内存\n");scanf("%d", &request);t = MI_SIZE;for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f'){flag = 1;if (MList[i].Size < t){t = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else {for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}int main(){int x;InitMList();while (1){printf(" \n"); printf(" 1.首次适应\n");printf(" 2.最佳适应\n");printf(" 3.最差适应\n"); printf(" 4.释放内存\n"); printf(" 5.显示内存\n"); printf(" 6.退出系统\n"); printf("请输入1-6:");scanf("%d", &x);switch (x){case 1:FirstFit();break;case 2:BestFit();break;case 3:BadFit();break;case 4:M_Release();break;case 5:Display();break;case 6:exit(0);}}return 0;}实验测试结果记录:1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存10---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 90 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 65 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存15---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 50 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存20---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:2---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 空闲3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:2最佳适应算法:请问你要分配多大的内存5---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:3最坏适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 25 使用6 95 5 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。
实现内存动态分区分配(首次算法)
3
protected void Copy(BusyNode BN){ this.Address=BN.Address; this.Size=BN.Size; this.ISConsume=BN.ISConsume; } protected int getAddress() {return Address;} protected void setAddress(int address) {Address = address;} protected boolean getIsISConsume() {return ISConsume;} protected void setISConsume(boolean consume) {ISConsume = consume;} protected int getSize() {return Size;} protected void setSize(int size) {Size = size;} } public static void main(String[] args) { MemoryManagement window = new MemoryManagement(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /*Open the window.*/ public void open() { Display display = Display.getDefault(); createContents(); shell.open(); yout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } /** Create contents of the window.*/ protected void createContents() { shell = new Shell(); shell.setForeground(SWTResourceManager.getColor(SWT.COLOR_GREEN)); shell.setSize(680, 418); shell.setText("操作系统内存管理"); SpareTable=new SpareNode[MaxProcessNum+1]; SpareTable[0]=new SpareNode(0,20000);
动态分区分配操作系统操作方法实验步骤
动态分区分配操作系统操作方法实验步骤1.引言1.1 概述概述部分:在计算机系统中,动态分区分配是一种重要的操作系统操作方法。
它是指在运行时根据进程的内存需求动态地将系统内存分配给进程,以实现内存资源的高效利用。
动态分区分配操作方法在现代操作系统中被广泛应用,例如Windows、Linux等。
通过合理的动态分区分配策略,可以提升系统的性能和资源利用率。
本文将对动态分区分配操作系统操作方法进行详细介绍和实验步骤的说明。
首先,我们将介绍动态分区分配的背景和意义,包括其在操作系统中的作用和应用场景。
其次,我们将详细讨论实验的具体步骤,包括如何进行动态分区分配操作、如何测试相关的性能指标等。
本文的目标是帮助读者了解动态分区分配操作系统操作方法的基本原理和实践技巧。
同时,通过实际操作和实验验证,读者将能够更好地理解动态分区分配的概念和操作过程,提升对操作系统的理解和应用能力。
在接下来的章节中,我们将分别介绍动态分区分配操作系统操作方法的背景和实验步骤,并给出相应的实例和案例分析。
最后,我们将对实验结果进行总结和展望,探讨动态分区分配操作方法的发展前景和可能的研究方向。
通过本文的阅读和实验操作,读者将能够对动态分区分配操作系统操作方法有一个全面的了解,为进一步研究和应用提供基础和指导。
同时,我们也欢迎读者对本文内容进行补充和扩展,以促进相关领域的进一步发展和应用。
1.2 文章结构文章结构部分的内容可以从以下角度进行描述:文章结构是指整篇文章的组织框架和内容安排。
合理的文章结构可以使读者更好地理解文章的主题和内容,帮助读者快速找到所需信息并形成完整的认识。
本文将按照以下结构进行论述:1. 引言:在引言部分,我们将对动态分区分配操作系统操作方法的背景和意义进行介绍,明确文章的目的和重要性。
2. 正文:正文是文章的核心部分,将分为两个要点进行叙述。
2.1 第一个要点:动态分区分配操作系统操作方法。
首先,我们将对动态分区分配的背景进行介绍,解释其在操作系统中的应用和意义。
操作系统实验四实验报告动态分区分配算法
操作系统实验四【实验题目】:动态分区分配算法【实验学时】:4学时【实验目的】通过这次实验,加深对动态分区分配算法的理解,进一步掌握首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的实现方法。
【实验内容及要求】问题描述:设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。
假设内存中空闲分区个数为n,空闲分区大小分别为P1, … ,P n,在动态分区分配过程中需要分配的进程个数为m(m≤n),它们需要的分区大小分别为S1, … ,S m,分别利用四种动态分区分配算法将m个进程放入n个空闲分区,给出进程在空闲分区中的分配情况。
程序要求:1)利用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法四种动态分区分配算法模拟分区分配过程。
2)模拟四种算法的分区分配过程,给出每种算法进程在空闲分区中的分配情况。
3)输入:空闲分区个数n,空闲分区大小P1, … ,P n,进程个数m,进程需要的分区大小S1, … ,S m。
4)输出:首次适应算法,循环首次适应算法,最佳适应算法,最坏适应算法,最终内存空闲分区的分配情况。
实现源代码:#include<iostream>#include<fstream>#include<iomanip>#include<string>#define max 100using namespace std;int work_num;int zone_num;struct Data{int data;char name;};Data *d=new Data[max];struct Table{int data;char array[max];int length;};Table *T=new Table[max];Table *temp=new Table[max];void Init(){ifstream inf("");int i,j;char ch;inf>>work_num;cout<<"作业数:"<<work_num<<endl;inf>>zone_num;cout<<"空闲分区数:"<<zone_num<<endl;cout<<" 作业为:";for(j=0;j<work_num;j++){(ch);d[j].name=ch;cout<<setw(4)<<d[j].name;}cout<<endl;cout<<"作业大小:";for(i=0;i<work_num;i++){inf>>d[i].data;cout<<setw(4)<<d[i].data;}cout<<endl;cout<<"空闲分区:";for(j=0;j<zone_num;j++){inf>>T[j].data;temp[j].data=T[j].data;T[j].length=0;temp[j].length=0;cout<<setw(4)<<T[j].data;}cout<<endl;}void renew(){int j;for(j=0;j<zone_num;j++){T[j].data=temp[j].data;T[j].length=temp[j].length;}}void re(){int i;for(i=0;i<zone_num;i++){T[i].array[T[i].length]='#';}}void show(){int i,j;re();for(i=0;i<zone_num;i++){if(T[i].data==temp[i].data)cout<<setw(4)<<T[i].data;else{cout<<setiosflags(ios::right)<<setw(4)<<T[i].data<<setw(1);for(j=0;j<T[i].length;j++){if(T[i].array[j]=='#')break;elsecout<<setiosflags(ios::right)<<T[i].array[j];}}}cout<<endl;}void first_fit(){renew();cout<<"fist fit:";int i,j;int tag=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}ata<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;m=j;break;}else{tag=1;count++;}}while(tag==1 && count<zone_num){for(j=0;j<m;j++){if(d[i].data<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;break;}else{tag=1;count++;}}}if(tag==1 && count==zone_num){cout<<"作业太大,无满足条件分区!"<<endl;break;}}ata<=T[j].data){temp=T[j].data;m=j;int tag1=0;for(k=m+1;k<=zone_num;k++){if(T[k].data<temp){if(T[k].data>=d[i].data){temp=T[k].data;n=k;tag1=1;}}else if(tag1==0)n=j;}T[n].data=temp - d[i].data;T[n].array[T[n].length]=d[i].name;T[n].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}ata<=T[j].data){int tag1=0;temp=T[j].data;m=j;for(k=m+1;k<=zone_num;k++){if(T[k].data>temp){if(T[k].data>=d[i].data){temp=T[k].data;n=k;tag1=1;}}else if(tag1==0)n=j;}T[n].data=temp - d[i].data;T[n].array[T[n].length]=d[i].name;T[n].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}//re();}void main(){Init();first_fit();show();next_fit();show();best_fit();show();worst_fit();show();system("pause");}实验截图:。
实验五动态分区分配算法的模拟
实验五动态分区分配算法的模拟为了更好地理解动态分区分配算法的工作原理,我们可以进行一次模拟实验。
在实验中,我们将模拟一个内存分区,并使用动态分区分配算法来管理这些分区。
首先,让我们定义一个内存大小为1000字节的分区。
我们假设这个内存中包含几个已分配的分区和几个空闲的分区。
我们使用首次适应算法来进行分区的首次适应分配。
首先,我们将整个内存空间标记为空闲状态,并创建一个初始的空闲链表。
我们假设初始时只有一个空闲分区,大小为1000字节,起始地址为0。
现在,假设有一个进程请求分配一个250字节大小的内存空间。
我们首先检查空闲链表,找到一个大小大于等于250字节的空闲分区。
在这种情况下,我们发现第一个空闲分区的大小是1000字节,所以我们将它拆分成250字节的已分配分区和750字节的空闲分区。
我们在已分配分区上标记一个进程编号,并将空闲分区加入空闲链表。
接下来,假设我们的进程需要申请500字节的内存空间。
在这种情况下,我们需要查找一个大小大于等于500字节的空闲分区。
我们发现第一个可用的空闲分区大小是750字节,我们将它拆分为已分配的500字节和剩余的250字节的空闲分区。
然后,我们假设有进程释放了先前分配的250字节的内存空间。
当一个进程释放分配的内存空间时,我们需要合并相邻的空闲分区。
在这种情况下,释放的分区位于地址0,大小为250字节,并且其下一个分区是地址500,大小为500字节的空闲分区。
因此,我们将这两个分区合并为一个大小为750字节的空闲分区。
接下来,我们假设另一个进程将请求600字节的内存空间。
根据首次适应算法,我们将在第一个满足条件的空闲分区进行分配。
在这种情况下,我们将分配200字节的空闲分区和分配400字节的空闲分区拆分为600字节的已分配分区和空闲分区。
最后,假设一个进程请求200字节的内存空间。
根据首次适应算法,我们在第一个满足条件的空闲分区进行分配。
在这种情况下,我们将250字节的空闲分区拆分为200字节的已分配分区和50字节的空闲分区。
实验五 动态分区分配算法的模拟
实验五动态分区分配算法的模拟一、实验目的1、加深操作系统内存管理过程的理解2、掌握内存分配算法的基本应用二、实验任务请同学们用C/C++实现一个完整的(可变)动态分区管理器,包括分配,回收,分区碎片整理等。
希望同学们实现如下功能:n 初始化功能:内存状态设置为初始状态。
n 分配功能:要求至少使用两种算法,用户可以选择使用。
n 回收功能:n 空闲块的合并:即紧凑功能,用以消除碎片。
当做碎片整理时,需要跟踪分配的空间,修改其引用以保证引用的正确性。
n 显示当前内存的使用状态,可以使用表格或图形。
三、实验指导1.基本思想动态分区是指系统不预先划分固定分区,而是在装入程序的时候划分内存区域,使得为程序分配的分区大小恰好等于该程序的需求量,且分区的个数是动态的。
显然动态分区有较大的灵活性,较之固定分区能获得好的内存利用率。
2.数据结构动态分区管理可以用两种数据结构实现,一种是已分配区表和空闲区表,也就是用预先定义好的系统空间来存放空间分配信息。
另一种也是最常用的就是空闲链表,由于对分区的操作是动态的,所以很难估计数据结构所占用的空间,而且空闲区表会占用宝贵的系统空间,所以提出了空闲链表的概念。
其特点是用于管理分区的信息动态生成并和该分区在物理地址上相邻。
这样由于可以简单用两个空闲块之间的距离定位已分配空间,不仅节约了系统空间,而且不必维持已分配空间的信息。
本实验是要做一个模拟程序,来模拟动态分区算法的分配和回收过程,并不是真正的去分配和回收内存。
基本的模拟方法有两种:1、先从内存中申请一块存储区,对这块存储区进行模拟的分配和回收活动。
2、不申请存储区,自己定义一块虚拟的存储区,对这块存储区进行模拟的分配和回收活动,分配和回收仅仅是对数据结构的修改而已。
程序代码:#include<iostream>using namespace std;int FreePartition[100];//空闲分区块数组int FirstPartition[100];//首次适应算法数组int CycleFirstPartition[100];//循环首次适应算法数组int BestPartition[100];//最佳适应算法数组int WorstPartition[100];//最坏适应算法数组int ProcessNeed[100];//每个作业的大小int PartitionNum,ProcessNum;//分区块数,作业数//首次适应算法void First(){int i,j;char str;for(i=0;i<PartitionNum;i++){FirstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++)//找出第一块满足作业的分区for(j=0;j<PartitionNum;j++){if(ProcessNeed[i]>FirstPartition[j])continue;else{FirstPartition[j]-=ProcessNeed[i];//找到后把分区大小减去作业的大小 ? ? ? ? ? ? ?str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;break;}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;?for(i=0;i<PartitionNum;i++)cout<<FirstPartition[i]<<" ";cout<<endl<<endl;}//循环首次适应算法void CycleFirst(){int i,j=1;char str;for(i=0;i<PartitionNum;i++){CycleFirstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++)//for(j=0;j<PartitionNum;j++){j=j-1;while(j<PartitionNum)if(ProcessNeed[i]>CycleFirstPartition[j])//continue;j++;else{CycleFirstPartition[j]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl; break;}//j++;//cout<<j<<" ";if(j==PartitionNum && i!=ProcessNum){i=-1;}}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<CycleFirstPartition[i]<<" ";cout<<endl<<endl;}//最佳适应算法void Best(){int i,j,k;char str;?for(i=0;i<PartitionNum;i++){BestPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++){k=0;for(j=0;j<PartitionNum;j++){//cout<<BestPartition[j]<<" ? "<<ProcessNeed[i]<<endl; if(BestPartition[j]>=ProcessNeed[i]){break;}}for(int n=0;n<PartitionNum;n++){if(BestPartition[n]<BestPartition[k] && BestPartition[n]>=ProcessNeed[i])//找最佳的 k=n;}BestPartition[k]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<BestPartition[i]<<" ";cout<<endl<<endl;}//最坏适应算法void Worst(){int i,j,k;char str;for(i=0;i<PartitionNum;i++){WorstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++){k=0;for(j=0;j<PartitionNum;j++){if(WorstPartition[j]>WorstPartition[k])//找到最大的分区k=j;}WorstPartition[k]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<WorstPartition[i]<<" ";cout<<endl<<endl;}void main(){int i;cout<<"输入分区块数:"<<endl;cin>>PartitionNum;cout<<"输入每个分区的大小:"<<endl;for(i=0;i<PartitionNum;i++)cin>>FreePartition[i];cout<<"输入作业数:"<<endl;cin>>ProcessNum;cout<<"输入每个作业的大小:"<<endl;for(i=0;i<ProcessNum;i++)cin>>ProcessNeed[i];cout<<"------------首次适应算法-----------------"<<endl; First();cout<<"------------循环首次适应算法-------------"<<endl; ?CycleFirst();cout<<"------------最佳适应算法-----------------"<<endl; Best();cout<<"------------最坏适应算法-----------------"<<endl; Worst();}。
操作系统实验二存储管理动态分区分配及回收算法
实验二存储管理动态分区分配及回收算法一、实验目的通过分区管理实验,了解操作系统的基本概念,理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。
通过课程设计,我们可以进一步理解在计算机系统上运行的其它各类操作系统,并懂得在操作系统的支持下建立自己的应用系统。
二、实验要求本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法和回收算法模拟程序,并掌握分配算法的特点,提高编程技巧和对算法的理解和掌握。
三、实验过程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. 当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。
若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。
4. 当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。
5. 设计的模拟系统中,进程数不小于5,进程调度方式可以采用实验一中的任何一种。
6. 运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。
首次适应算法将内存中的空闲区按照地址由低到高的顺序形成空闲区表当一个新作业要求装入主存时,查空闲区表,从中找到第一个满足要求的空闲区,为作业分配主存空间,并将剩余空闲区按照地址由小到大的顺序插入空闲区表的合适位置,修改已分配表当作业运行结束后,回收作业的主存空间,并与相邻空闲区合并,修改空闲区表和已分配表每次主存分配和回收后,打印空闲区表和已分配表详细描述实验设计思想、程序结构及各模块设计思路;详细描述程序所用数据结构及算法;明确给出测试用例和实验结果;为增加程序可读性,在程序中进行适当注释说明;认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;#include<iostream>#include<cstdlib>using namespace std;const int procsize=5;typedef struct Node{int PId; //进程Idint Prio; //进程优先数int NeedRunTime; //进程需要运行时间int Room; //进程所需空间大小Node * next; //就绪队列中的下个就绪进程的地址}PCB;typedef struct{ //就绪链式队列结构体PCB *front;PCB *rear;}AleadyQueue;typedef struct Tab{ //分区表结构体int CalledId; //调用该分区的进程Idint TabId; //分区号int Size; //大小int StartAdd; //始址char * Status; //使用状态Tab *next; //指向下个分区}Table;void CinInfo(PCB P[procsize]){ //输入进程信息cout<<"\t\t请输入5个进程,格式如下:\n\n ";cout<<"PId 优先数运行时间所需内存大小(最好是小于20)\n";int i=0,j=0;for(i,j; i<procsize ; i++,j++){cin>>P[j].PId>>P[j].Prio>>P[j].NeedRunTime>>P[j].Room;}}void Sort(PCB P[procsize]){ //根据优先数由冒泡法对进程进行排序int i,j,exchange=1; //exchange表示相邻PCB是否调换PCB Temp;for(i=procsize;i>1&&exchange;i--){exchange=0;for(j=0;j<i-1;j++)if(P[j].Prio<P[j+1].Prio){Temp=P[j];P[j]=P[j+1];P[j+1]=Temp;exchange=1;}}}AleadyQueue InitQueue(){ //就绪队列初始化函数AleadyQueue Q;Node *p;p=(Node *)malloc(sizeof(PCB));if(!p){cout<<"就绪队列初始化失败!\n";exit(0);}else{Q.front=Q.rear=p;Q.front->next=NULL;return Q;}}void EnQueue(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}void EnQueue1(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}PCB OutQueue(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}PCB OutQueue1(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}void printinfo(AleadyQueue Q){ //打印就绪队列的情况cout<<"目前就绪队列进程情况如下:\n";cout<<"PId\t\tPriority\t\tNeedTime\t\tRoom\n";Q.front=Q.front->next;while(1){if(Q.front!=NULL){cout<<Q.front->PId<<"\t\t"<<Q.front->Prio<<"\t\t\t";cout<<Q.front->NeedRunTime<<"\t\t\t"<<Q.front->Room<<endl;Q.front=Q.front->next;}elsebreak;}}int chose(){ //选择所选算法int i;cout<<"请选择:\n";cout<<" 1、采用<首次适应>算法为进程分配内存!\n";cout<<" 2、采用<最佳适应>算法为进程分配内存!\n";cout<<" 3、采用<最坏适应>算法为进程分配内存!\n";cout<<" 4、结束!\n";cin>>i;return i;}Table * CreateMMTable(){ //定义主存分区表Table * FT; //用尾插入法Table * R;Table * P;FT=(Table *)malloc(sizeof(Tab));R=FT;FT->next=NULL;int num=0;int LastAdd=0;int LastSize=1;while(1){P=(Table *)malloc(sizeof(Tab));P->CalledId=0; //被调用的进程调Id初始化为0P->TabId=num; //主存分区号P->Size=3*num+1; //分区大小P->StartAdd=LastAdd+LastSize; //分区始址P->Status="Free"; //分区状态num++; //分区号加1LastAdd=P->StartAdd; //重新定义LastAdd为上次的StartAddLastSize=P->Size; //同上P->next=NULL;R->next=P;R=P;if(P->StartAdd==93) //内存初始化完毕break;}return FT;}Table * CreateUsedTable(){ //创建已分配表Table * T;T=(Table *)malloc(sizeof(Tab));T->next=NULL;return T;}void CoutMMTable(Table * FTL){ //打印主存表情况cout<<"主存表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";cout<<FTL->Status<<endl;FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutFreeTable(Table * FTL){ //打印空闲区表cout<<"空闲区表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";printf("%s\n",FTL->Status);FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutUsedTable(Table * UTL){ //打印已分配表cout<<"已分配表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";UTL=UTL->next;while(1){if(UTL->Status=="Used"){cout<<UTL->TabId<<"\t\t"<<UTL->StartAdd<<"\t\t";cout<<UTL->Size<<"\t\t";printf("%s\n",UTL->Status);}UTL=UTL->next;if(UTL->next==NULL)break;}}int DistribMM(Table * MMTableList,PCB Temp,Table * FTL,Table * UTL){//分配一块一定大小的内存Table *P;Table * TempMM; //需要改为已分配节点的上一个节点TempMM=MMTableList;Table * TTT;TTT=MMTableList->next;while(1){ //查找满足大小的分区节点if(TTT->Size>=Temp.Room && TTT->Status=="Free")break;TTT=TTT->next;if(TTT==NULL){cout<<"\n\n\n\t\t\t\t警告!内存不足....\n\n\n";return 0;}}//while//以下是内存改为已分配P=(Table *)malloc(sizeof(Tab));while(1){if(TempMM->next==TTT)break;TempMM=TempMM->next;}P->next=TempMM->next;TempMM->next=P;P->StartAdd=TTT->StartAdd;P->Size=Temp.Room;P->CalledId=Temp.PId;P->TabId=TTT->TabId;P->Status="Used";P=P->next;while(P!=NULL){(P->TabId)++;P=P->next;}FTL=FTL->next;while(1){ //将空闲分区对应的首地址更改if(FTL->StartAdd==TTT->StartAdd)break;FTL=FTL->next;}TTT->StartAdd=FTL->StartAdd=TTT->StartAdd+Temp.Room;//空闲表的首地址=原来+Room TTT->Size=FTL->Size=TTT->Size-Temp.Room;while(FTL!=NULL){(FTL->TabId)++;FTL=FTL->next;}return 2;}void ReturnMM(Table * MMTableList,Table * FTL,Table * UTL,PCB &Temp){ //回收一块内存MMTableList=MMTableList->next;FTL=FTL->next;Table *TT;while(1){if(MMTableList->CalledId==Temp.PId){if(MMTableList->next->Status=="Free"){MMTableList->Status="Free"; //修改内存,相邻的为FreeMMTableList->CalledId=0;MMTableList->Size=MMTableList->Size+MMTableList->next->Size;MMTableList->next=MMTableList->next->next;TT=MMTableList;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}if(MMTableList->next->Status!="Free"){MMTableList->Status="Free"; //修改内存,相邻的为USedMMTableList->CalledId=0;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}}if(MMTableList->next==NULL)break;MMTableList=MMTableList->next;}//总whilecout<<"\n";}int FF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q){ //首次适应算法PCB Temp;int i; //记录分配函数的返回值0int num=0; //记录进程首次分配内存while(1){Temp=OutQueue(Q);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; //内存不足CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==1){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==2){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; // printf("y余朝水\n");CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==3){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==4){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";if(Temp.PId==5)return 1;ReturnMM(MMTableList,FTL,UTL,Temp); //回收内存CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表printinfo(Q);if(Q.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue(Q,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}int BF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最佳适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组PQ2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 1;}int WF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最坏适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}void main(){AleadyQueue Q1; //定义一个就绪队列AleadyQueue Q2;AleadyQueue Q3;PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q1=InitQueue(); //就绪队列初始化Q2=InitQueue();Q3=InitQueue();for(int k=0; k<procsize; k++)EnQueue(Q1,P[k]); //首次排好序的就绪进程入队,//进程依次等待处理机调度for(k=0; k<procsize; k++)EnQueue(Q2,P[k]);for(k=0; k<procsize; k++)EnQueue(Q3,P[k]);printinfo(Q1); //打印当前就绪队列的情况Q3=Q2=Q1;Table * MMTableList; //主存分区表Table * MM;Table * FreeTableList; //空闲分区表Table * UsedTableList; //已分配分区表MMTableList=CreateMMTable(); //创建主存分区表MM=CreateMMTable();FreeTableList=CreateMMTable(); //创建空闲分区表(初始化时和内存分区表相同)UsedTableList=CreateUsedTable(); //创建已分配表CoutMMTable(MMTableList); //打印主存分区表int i; //记录0,内存不足int j; //记录所选算法while(1){j=chose(); //判断所选算法,所需操作(FF、BF、WF)if(j==1)i=FF(MM,FreeTableList,UsedTableList,Q1);//首次适应算法if(i==0)exit(0); //内存不足if(j==2)i=BF(MM,FreeTableList,UsedTableList,Q2);//最佳适应算法if(i==0)exit(0); //内存不足if(j==3)i=WF(MM,FreeTableList,UsedTableList,Q3);//最坏适应算法if(i==0)exit(0); //内存不足if(j==4)break; //结束内存分配}cout<<"\n\n\n-----------------------------------欢迎使用!------------------------------------\n\n\n\n\n"; }。
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。
二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。
具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。
三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。
当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。
回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。
如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。
四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。
五、实验步骤第一,设计记录内存使用情况的数据表格λ已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)λ空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table { float address;//已分分区起始地址float length;//已分分区长度,单位为字节int flag;//已分配表区登记栏标志,用0表示空栏目,char zuoyename;};//已分配区表Struct free_table[ { float address;//空闲分区起始地址float length;//空闲分区长度,单位为字节int flag;//空闲分区表登记栏目用0表示空栏目,1表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。
【操作系统】分区分配算法(首次适应算法、最佳适应算法)(C语言实现)
【操作系统】分区分配算法(⾸次适应算法、最佳适应算法)(C语⾔实现)【操作系统】分区分配算法(⾸次适应算法、最佳适应算法)(C语⾔实现)(编码⽔平较菜,写博客也只是为了个⼈知识的总结和督促⾃⼰学习,如果有错误,希望可以指出)今天测试,发现⼀点问题:1.最佳插⼊算法:对于插⼊的时候忘记修改temp.next.front的指向2.回收头节点的时候现在多了⼀种判断。
判断头节点的下⼀个是否为空。
对如果不为空⽽且后⾯的空闲的话,做出了处理。
原来则没有这⼀情况。
1.动态分区分配算法:为了实现动态分区分配,通常将系统中的空闲分区链接成⼀个链。
所谓顺序查找是指依次搜索空闲分区链上的空闲分区,去寻找⼀个⼤⼩能满⾜要求的分区。
--------计算机操作系统(第四版)2.动态分区算法主要包括四种:(1).⾸次适应算法(first fit,FF):要求,空闲分区链以地址递增的顺序链接。
每次从链⾸开始,直到找到第⼀个能满⾜要求的空闲分区为⽌。
简单来说,就是,每次都从第⼀个开始顺序查找,找到⼀块区域可以满⾜要求的。
优点:优先利⽤内存中低址部分的空闲分区,从⽽保留了⾼址部分的⼤空闲区,这为以后到达的⼤作业分配⼤的内存空间创造了条件。
缺点:低址部分不断被划分,会留下许多难以利⽤的,很⼩的空闲分区,称为碎⽚。
⽽每次查找⼜都是从低址部分开始的,这⽆疑⼜会增加查找可⽤空闲分区时的开销。
(2).循环⾸次适应算法(next fit,NF):与FF算法区别就是,不是每次都从⾸次开始,⽽是从上次找到的空闲分区的下⼀个空闲分区开始。
(第⼀次查找的话也是从⾸页开始)。
特点:能使内存中的空闲区分布得较均匀。
(3).最佳适应算法(best,BF):将所有空闲分区按照空闲分区容量⼤⼩从⼩到⼤的顺序连接起来,形成⼀个空闲分区链。
即,每次都是找空间容量不但可以满⾜要求的空闲区,⽽且该空闲分区的容量还要最接近要求的容量⼤⼩。
优点:每次分配给⽂件的都是最合适该⽂件⼤⼩的分区。
动态分区分配算法
动态分区分配算法动态分区分配算法⼀实验内容与要求内容:动态分区分配是根据进程的实际需要,动态地为之分配内存空间,⽽在分配时,须按照⼀定的分配算法,从空闲分区表或空闲分区链中选出⼀分区分配给该作业。
在本实验中运⽤了三种分配算法,分别是1.⾸次适应算法,2.循环⾸次适应算法,3.最佳适应算法。
要求:动态分区算法也称为可变分区分配算法,常见的空闲区查找算法有⾸次适应算法,循环⾸次适应算法,最佳适应算法。
特别注意分区回收时,相邻空闲分区需要合并。
(1)参考操作系统教材理解这3种分配算法以及回收算法。
(2)实现3种分配算法以及回收算法。
(3)已知作业申请内存和释放内存的序列,给出内存的使⽤情况。
(4)作业申请内存和释放内存的序列可以存放在⽂本⽂件中。
(5)设计简单的交互界⾯,演⽰所设计的功能。
(可以使⽤MFC进⾏界⾯的设计)(6)可根据⾃⼰能⼒,在完成以上基本要求后,对程序功能进⾏适当扩充。
⼆、需求分析本次实验通过⽤C语⾔进⾏编程并调试、运⾏,形象地表现出动态分区的分配⽅式,直观地展现了⾸次适应算法和最佳适应算法对内存的释放和回收⽅式之间的区别。
加深了我们对两种算法优缺点的理解,帮助我们了解⼀些数据结构和分配算法,进⼀步加深我们对动态分区存储器管理⽅式及其实现过程的理解。
主要的问题在于,如何解决两种算法对内存的释放和回收空间的表⽰。
动态分区分配:⼜称为可变分区分配,这种分配⽅式并不事先先将主存划分成⼀块块的分区,⽽是在作业进⼊主存时,根据作业的⼤⼩动态地建⽴分区。
并使分区的⼤⼩正好适应作业的需要。
因此系统中分区的⼤⼩是可变的,分区的数⽬也是可变的。
分区分配算法:1.⾸次适应法:为作业选择分区时总是按地址从⾼到低搜索,只要找到可以容纳该作业的空⽩块,就把该空⽩块分配给该作业。
特点:优先利⽤内存中底地址部分的空闲分区 (将所有空闲区,按其地址递增的顺序链接)2.循环⾸次适应算法该算法是由⾸次适应算法演变⽽成,在为进程分配内存空间时,不再是每次都从第⼀个空间开始查找,⽽是从上次找到的空闲分区的下⼀个空闲分区开始查找,直⾄找到第⼀个能满⾜要求的空闲分区,从中划出⼀块与请求⼤⼩相等的内存空间分配给作业,为实现本算法,设置⼀个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到⼀个满⾜要求的分区,则此次内存分配失败。
动态分区分配方式的模拟实验原理说明
动态分区分配方式的模拟实验原理说明一、引言动态分区分配方式是计算机内存管理中一种常见的分配方式,它将内存按需划分为多个独立的区域,用于分配进程所需的内存空间。
本文将详细探讨动态分区分配方式的原理及其在模拟实验中的应用。
二、动态分区分配方式的原理动态分区分配方式基于内存动态分配,将可用内存划分为多个不连续的分区,每个分区可用于存放一个进程或程序。
此分配方式具有灵活性,能够更好地满足不同程序对内存空间的需求。
2.1 空闲内存分区列表在动态分区分配方式中,操作系统维护一个空闲内存分区列表,记录可供分配的内存空间情况。
列表中的每个分区都有其起始地址和长度。
2.2 分区分配算法动态分区分配方式有多种分区分配算法可供选择,主要包括首次适应算法、最佳适应算法和最差适应算法。
•首次适应算法:从空闲分区列表中找到第一个满足分配要求的分区进行分配。
•最佳适应算法:从空闲分区列表中找到最小的满足分配要求的分区进行分配。
•最差适应算法:从空闲分区列表中找到最大的满足分配要求的分区进行分配。
2.3 分区回收算法当进程结束或释放内存时,操作系统需要将其占用的内存空间回收,归还给空闲内存区。
分区回收算法的目标是尽可能地合并相邻的空闲区域,以最大程度地提供可用内存。
三、动态分区分配方式的模拟实验为了更好地理解和研究动态分区分配方式,可以进行一系列模拟实验。
下面将介绍动态分区分配方式的模拟实验原理及步骤。
3.1 实验原理动态分区分配方式的模拟实验基于以下原理: - 创建一个内存模拟环境,模拟操作系统管理的内存空间。
- 设计一系列测试用例,模拟进程的创建、分配和回收过程。
- 根据所选的分区分配算法和分区回收算法,计算分区分配和回收的效果。
- 比较不同算法在性能方面的差异,并分析其优缺点。
3.2 实验步骤动态分区分配方式的模拟实验包括以下步骤: 1. 初始化内存模拟环境,创建一个空闲分区列表。
2. 设计多个测试用例,包括不同大小和数量的进程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告实验2 动态分区分配算法报告日期:2016-6-15姓名:学号:班级:任课教师:5k 10k 14k 26k 32k512k实验2 动态分区分配算法一、实验内容编写一个内存动态分区分配模拟程序,模拟内存的分配和回收的完整过程。
二、实验目的一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间的分配和回收。
三、实验原理模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收。
(1)可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。
随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。
例如:为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:第一栏 第二栏其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区。
(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。
有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。
为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。
为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。
(3) 采用最先适应算法(顺序分配算法)分配主存空间。
按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。
当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。
由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。
(4) 当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。
(5) 请按最先适应算法设计主存分配和回收的程序。
假设初始时主存中没有作业,现按下面序列进行内存的申请与释放:作业1申请300K,作业2申请100K,作业1释放300K,作业3申请150K,作业4申请30K,作业5申请40K,作业6申请60K,作业4释放30K。
请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。
四、实验报告1. 画出算法流程图。
2. 源代码#define_CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#define N 10000int n1;//空闲分区的个数int n2;//作业区的个数struct kongxian{int start; //起址int end; //结束int length; //长度}kongxian[N];struct zuoye{int start; //起址int end; //结束int length; //长度}zuoye[N];int cmp1(const void *a, const void *b){return (*(struct kongxian *)a).start - (*(struct kongxian*)b).start;}int cmp2(const void *a, const void *b){return (*(struct zuoye *)a).start - (*(struct zuoye *)b).start; }void init(){n1 = 1; //初始时只有一个空闲区n2 = 0; //初始没有作业kongxian[0].start = 0;kongxian[0].end = 511;kongxian[0].length = 512;}void print1() //打印空闲分区{int i;for (i = 0; i<n1; i++)printf("空闲分区ID:%d 起止:%d 结束:%d 长度:%d\n", i,kongxian[i].start, kongxian[i].end, kongxian[i].length);}void print2() //打印作业分区{int i;for (i = 0; i<n2; i++)printf("作业分区ID:%d 起止:%d 结束:%d 长度:%d\n", i,zuoye[i].start, zuoye[i].end, zuoye[i].length);}int main(){int i, j, t, len, flag, id;int front, middle, behind;int t1, t2;init();print1();printf("输入1装入新作业,输入0回收作业,输入-1结束\n");while (scanf("%d", &t) != EOF){if (t == 1) //装入新作业{printf("请输入作业的占用空间的长度 ");scanf("%d", &len);flag = 0;for (i = 0; i<n1; i++){if (kongxian[i].length >= len) //首次适应算法{flag = 1;break;}}if (!flag){printf("内存分配失败\n");}else{//将该作业加入作业区里zuoye[n2].start = kongxian[i].start;zuoye[n2].end = zuoye[n2].start + len;zuoye[n2].length = len;n2++; //作业数加1if (kongxian[i].length == len) //该分区全部用于分配,删除该空闲分区{for (j = i; j<n1 - 1; j++){kongxian[j].start = kongxian[j + 1].start;kongxian[j].end = kongxian[j + 1].end;kongxian[j].length = kongxian[j + 1].length;}n1--;}else//该空闲分区部分用于分配,剩余的留在空闲分区中{kongxian[i].start += len;kongxian[i].length -= len;}}}else if (t == 0){printf("输入要回收的作业ID ");scanf("%d", &id);front = middle = behind = 0;for (i = 0; i<n1; i++){if (kongxian[i].start>zuoye[id].end)break;if (kongxian[i].end == zuoye[id].start) //待回收的作业上面有空闲分区{front = 1;t1 = i;}if (kongxian[i].start == zuoye[id].end) //待回收的作业下面有空闲分区{behind = 1;t2 = i;}}if (!front&&!behind) //待回收的作业上下均没有空闲分区{kongxian[n1].start = zuoye[id].start;kongxian[n1].end = zuoye[id].end;kongxian[n1].length = zuoye[id].length;n1++; //空闲分区增加一个qsort(kongxian, n1, sizeof(struct kongxian), cmp1); //插入空闲分区后排序for (j = id; j<n2 - 1; j++) //在作业分区中删除该作业{zuoye[j].start = zuoye[j + 1].start;zuoye[j].end = zuoye[j + 1].end;zuoye[j].length = zuoye[j + 1].length;}n2--;}if (front &&behind) //待回收的作业上下均有空闲分区middle = 1;if (front&&!middle) //合并待回收的作业和上面的空闲分区{kongxian[t1].end += zuoye[id].length;kongxian[t1].length += zuoye[id].length;for (j = id; j<n2 - 1; j++) //在作业分区中删除该作业{zuoye[j].start = zuoye[j + 1].start;zuoye[j].end = zuoye[j + 1].end;zuoye[j].length = zuoye[j + 1].length;}n2--;}if (middle) //合并待回收的作业和上下的空闲分区{kongxian[t1].end = kongxian[t2].end;kongxian[t1].length +=(zuoye[id].length +kongxian[t2].length);//删除空闲分区t2for (j = t2; j<n1 - 1; j++){kongxian[j].start = kongxian[j + 1].start;kongxian[j].end = kongxian[j + 1].end;kongxian[j].length = kongxian[j + 1].length;}n1--;for (j = id; j<n2 - 1; j++) //在作业分区中删除该作业{zuoye[j].start = zuoye[j + 1].start;zuoye[j].end = zuoye[j + 1].end;zuoye[j].length = zuoye[j + 1].length;}n2--;}if (behind &&!middle) //合并待回收的作业和下面的分区{kongxian[t2].start -= zuoye[id].length;kongxian[t2].length += zuoye[id].length;for (j = id; j<n2 - 1; j++) //在作业分区中删除该作业{zuoye[j].start = zuoye[j + 1].start;zuoye[j].end = zuoye[j + 1].end;zuoye[j].length = zuoye[j + 1].length;}n2--;}}else{printf("操作结束\n");break;}print1();print2();}return 0;}3.程序运行时的初值和运行结果。