实验四动态分区分配算法实验分析报告及程序

合集下载

实验四动态分区分配算法实验报告及程序

实验四动态分区分配算法实验报告及程序

实验报告四动态分区分配算法班级学号姓名一、实验目的动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。

在本实验中运用了四种分配算法,分别是1.首次适应算法,2.循环首次适应算法,3.最坏适应算法4.最佳适应算法。

二、实验环境普通的计算机一台,编译环境Microsoft Visual C++ 6.0三、算法思想1.数据结构(1)分区开始地址startaddress(2)分区大小size(3)分区状态state2.功能介绍(1)首次适应算法在首次适应算法中,是从已建立好的数组中顺序查找,直至找到第一个大小能满足要求的空闲分区为止,然后再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空间令开辟一块新的地址,大小为原来的大小减去作业大小,若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(2)循环首次适应算法该算法是由首次适应算法演变而成,在为进程分配内存空间时,不再是每次都从第一个空间开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业,为实现本算法,设置一个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(3)最坏适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最大的空闲分区分配给作业。

(4)最佳适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最小的空闲分区分配给作业。

四、源程序#include <stdio.h>#define L 10typedef struct LNode{int startaddress;int size;int state;}LNode;LNodeP[L]={{0,128,0},{200,256,0},{500,512,0},{1 500,1600,0},{5000,150,0}};int N=5; int f=0;void print(){ int i;printf("起始地址分区状态\n");for(i=0;i<N;i++)printf("%3d %8d %4d\n",P[i].startaddress, P[i].size,P[i].state);}void First(){ int i,l=0,m;printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break; }else{P[N].startaddress=P[i].startaddress+m;P[N].size=P[i].size-m;P[i].size=m;P[i].state=1;l=1; N++;break; } }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void CirFirst(){ int l=0,m,t=0;printf("\n输入请求分配分区的大小:");scanf("%d",&m);while(f<N){ if(P[f].size<m){ f=f+1;if(f%N==0){ f=0;t=1;}continue; }if(P[f].size==m && P[f].state!=1){ P[f].state=1;l=1; f++;break; }if(P[f].size>m && P[f].state!=1){ P[N].startaddress=P[f].startaddress+m;P[N].size=P[f].size-m;P[f].size=m;P[f].state=1;l=1; N++;f++; break; } }if(l==1){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Worst(){int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1; break; }elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]>a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Best(){ int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break;}elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]<a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void main(){ int k=0;printf("动态分区分配算法:");while(k!=5){printf("\n~~~~~~~~主菜单~~~~~~~~~");printf("\n1、首次适应算法\n2、循环首次适应算法");printf("\n3、最坏适应算法\n4、最佳适应算法");printf("\n5、退出\n");printf("请选择算法:");scanf("%d",&k);switch(k){ case 1:printf("\n初始状态为:\n");print();First();continue;case 2:printf("\n初始状态为:\n");print();CirFirst();continue;case 3:printf("\n初始状态为:\n"); print();Worst();continue;case 4:printf("\n初始状态为:\n");print();Best();continue;case 5:break;default:printf("选择错误,请重新选择。

实验报告-动态分区分配算法

实验报告-动态分区分配算法

南昌大学实验报告学生姓名:马江涛学号: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):当要分配内存空间时,就查找空闲表中满足要求的空闲块,并使得剩余块是最小的。

然后把它分配出去,若大小恰好合适,则直按分配;若有剩余块,则仍保留该余下的空闲分区,并修改分区大小的起始地址。

内存回收:将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。

动态分区分配

动态分区分配

操作系统课程设计动态分区分配学院专业学号学生姓名指导教师姓名2014年3月12日目录一、引言 (1)二、总体设计 (2)1. 数据处理类设计 (2)2. 相关消息映射设计 (3)3. 相关流图 (5)三、实验验证 (6)1. 结果截图 (6)2. 代码分析 (9)四、总结 (15)五、参考资料 (16)一、引言连续分配方式,是指为一个用户程序分配一个连续的内存空间。

这种分配方式曾被广泛应用于20世纪60~70年代的OS中,它至今仍在内存分配方式中占有一席之地;又可把连续分配方式进一步分为单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种方式。

动态分区分配是根据进程的实际需要,动态地为之分配内存空间。

在实现可变分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操作这样的三个问题。

最佳适应算法(best fit)所谓“最佳”是指每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作业,避免“大财小用”。

为了加速寻找,该算法要求将所有的空闲分区按其容量以从小到大的顺序形成一个空闲分区链。

这样,第一次找到的能满足要求的空闲区,必然是最佳的。

最坏适应算法(worst fit)最坏适应算法与最佳适应算法对应,具体实现过程中,仅仅对空闲分区链的创建不同。

最坏适应算法是以从大到小的方式创建的。

本次课设,对最佳适应算法与最坏适应算法两种算法进行模拟,程序的数据处理由标准的C++类设计完成。

程序采用了可视化程序界面的设计方法,协调完成各项要求。

【关键词】操作系统课设,动态分区分配,C++,MFC。

二、总体设计1.数据处理类设计数据处理是本次实验的设计的核心,具体算法的实现均是在此类中设计完成的。

作业节点类(class pcb)作为内嵌类,该类的主要作用是作为相关分区链节点。

该类的定义如下:class pcb{private:int ID;int FirstAddr;int len;int arrive_time;int holding_time;int run_time;public:pcb() { ID = 0; FirstAddr = len = arrive_time = holding_time = run_time = 0; }void setID(int N) { ID = N; }void setFA(int fa) { FirstAddr = fa; }void setLen(int l) { len = l; }void setAT(int at) { arrive_time = at; }void setHT(int ht) { holding_time = ht; }void setRT(int rt) { run_time = rt; }int getFA() const { return FirstAddr; }int getLen() const { return len; }int getAT() const { return arrive_time; }int getHT() const { return holding_time; }int getRT() const { return run_time; }int getID() const { return ID; }};分区链类主要处理空闲分区节点和作业节点的分配,实现最佳分配算法和最坏分配算法。

动态内存分配实验报告

动态内存分配实验报告

Free[free_p].len=length;
free_p++;
//
sort(Free,Free+free_p,cmp);
for(j=0;j<free_p;j++)
{
1].address)
if(j + 1 < free_p&&Free[j].address+Free[j].len==Free[j +
if(used[i].run_id==id) {
int add=used[i].address; int length=used[i].len; used_p--; for(j=i;j<used_p;j++) {
used[j]=used[j+1]; }
Free[free_p].address=add;
Free[i].address+=len; Free[i].len-=len; } else { free_p--;
for(j=i;j<free_p;j++) {
Free[j]=Free[j+1]; } } break; } }
} void reclaim(int id) {
int i,j,k; for(i=0;i<used_p;i++) {
{ Free[j].len+=Free[j + 1].len; free_p--; for(k =j + 1; k < free_p;k++) { Free[k]=Free[k+1]; }
}
}
} }
} void show() {

实验四动态分区分配算法

实验四动态分区分配算法

实验容:存储器管理实验一、实验目的采用首次适应算法〔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、分区的初始化——可以由用户输入初始分区的大小。

(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。

4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。

(注意:不存在的作业号要给出错误提示!)5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)6、要求考虑:(1)内存空间不足的情况,要有相应的显示;(2)作业不能同名,但是删除后可以再用这个名字;(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。

#include "iostream.h"#include "iomanip.h"#define ERR_NOFREEAREA 1#define ERR_NOADEQUACYAREA 2#define ERR_ALLOCATED 4#define ERR_NOJOBS 1#define ERR_NOSUCHJOB 2#define ERR_RECLAIMED 4typedef struct tagUsedNode{long address;long length;int flag;//作业名struct tagUsedNode *next;}USED_AREA, *USED_TABLE;typedef struct tagFreeNode{long address;long length;struct tagFreeNode *next;}FREE_AREA, *FREE_TABLE;//空闲区、作业区链表USED_TABLE usedTable=NULL;FREE_TABLE freeTable=NULL;//给作业分配空间int Allocate(int jobname,long jobsize){//如果没有空闲区if(freeTable==NULL)return ERR_NOFREEAREA;FREE_TABLE p=freeTable;FREE_TABLE q=p;//找首次适应空闲区while(p!=NULL&&p->length<jobsize){q=p;p=p->next;}//如果找不到有足够空间的分区if(p==NULL)return ERR_NOADEQUACYAREA;USED_TABLE x=new USED_AREA;x->address=p->address;x->length=jobsize;x->flag=jobname;x->next=NULL;//如果该分区大于作业需求,空间大小减去作业大小if(p->length>jobsize){p->length-=jobsize;p->address+=jobsize;}//如果该分区等于作业大小,删除该分区else{if( p==freeTable)freeTable=NULL;elseq->next=p->next;delete p;}//作业加入"作业表"中USED_TABLE r=usedTable;USED_TABLE t=r;while(r!=NULL&&r->address<x->address) {t=r;r=r->next;}if(usedTable==NULL)usedTable=x;else{x->next=r;t->next=x;}return ERR_ALLOCATED;}//回收作业空间int Reclaim(int jobname){if(usedTable==NULL)return ERR_NOJOBS;USED_TABLE p=usedTable;USED_TABLE q=p;while(p!=NULL&&p->flag!=jobname) {q=p;p=p->next;}//如果没有该作业if(p==NULL)return ERR_NOSUCHJOB;//回收后的空间加入到空闲区FREE_TABLE r=freeTable;FREE_TABLE t=r;FREE_TABLE x;while(r!=NULL&&r->address<p->address) {t=r;r=r->next;}x=new FREE_AREA;x->address=p->address;x->length=p->length;x->next=NULL;if(r==freeTable ){x->next=r;freeTable=x;t=freeTable;}else{x->next=r;t->next=x;}//合并分区while(t->next!=NULL&&t->address+t->length==t->next->address) {t->length+=t->next->length;r=t->next;t->next=t->next->next;delete r;}//删除作业if( p==usedTable){usedTable=usedTable->next;}elseq->next=p->next;delete p;return ERR_RECLAIMED;}int Init(){freeTable=new FREE_AREA;freeTable->address=0;freeTable->length=1024;freeTable->next=NULL;return 1;}void jobrequest(){int jobname;int jobsize;cout<<"\n************************"<<endl;cout<<"作业名: ";cin>>jobname;cout<<"作业长度: ";cin>>jobsize;if(Allocate(jobname,jobsize)==ERR_ALLOCATED)cout<<"该作业已成功获得所需空间"<<endl;elsecout<<"该作业没有获得所需空间"<<endl;cout<<"************************\n"<<endl;}void jobreclaim(){int jobname;cout<<"\n************************"<<endl;cout<<"作业名: ";cin >>jobname;int result=Reclaim(jobname);if(result==ERR_RECLAIMED)cout<<"该作业已成功回收"<<endl;else if(result==ERR_NOSUCHJOB||result==ERR_NOJOBS)cout<<"该作业不存在,请重新输入"<<endl;cout<<"************************\n"<<endl;}void freeTablePrint(){cout<<"\n*****************************************"<<endl;cout<<setw(10)<<"地址"<<setw(10)<<"大小"<<setw(10)<<"状态"<<endl<<endl;FREE_TABLE p=freeTable;USED_TABLE q=usedTable;int x,y;while(p||q){if(p)x=p->address;elsex=0x7fffffff;if(q)y=q->address;elsey=0x7fffffff;if(x<y){cout<<setw(10)<<p->address<<setw(10)<<p->length<<setw(10)<<"空闲"<<endl;p=p->next;}if(x>y){cout<<setw(10)<<q->address<<setw(10)<<q->length<<setw(10)<<"已分配"<<setw(10)<<"ID="<<q->flag<<endl;q = q->next;}}cout<<"*****************************************\n"<<endl;}void main(){Init();int choose;bool exitFlag = false;while(!exitFlag){cout<<"-----------------------输入选择项-----------------------"<<endl;cout<<"------ 1 分配分区 2 回收分区 3 显示分区 4 退出------"<<endl;cout<<"--------------------------------------------------------\n"<<endl;cout<<"选择: ";cin>>choose;switch(choose){break;case 1:jobrequest();break;case 2:jobreclaim();break;case 3:freeTablePrint();break;case 4:exitFlag=true;}}}。

动态分区算法实验报告

动态分区算法实验报告

动态分区算法实验报告动态分区算法实验报告一、引言计算机操作系统是现代计算机系统中的核心组成部分,它负责管理计算机硬件资源,并提供各种服务。

内存管理是操作系统的重要功能之一,它负责管理计算机的内存资源,为进程提供运行环境。

在内存管理中,动态分区算法是一种常用的内存分配策略。

本实验旨在通过实践,深入了解动态分区算法的原理和实现。

二、实验目的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:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。

实验四 操作系统存储管理实验报告

实验四  操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。

二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。

离散分配:分页存储管理、分段存储管理、段页式存储管理。

2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。

最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。

最坏适应算法:选择最大的空闲分区进行分配。

3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。

四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。

输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。

2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。

输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。

3、离散内存分配实验实现分页存储管理的地址转换功能。

输入逻辑地址,程序计算并输出对应的物理地址。

4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。

记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。

五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。

内存状态显示清晰,分区的使用和空闲情况一目了然。

动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。

2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤1.引言1.1 概述概述部分:在计算机系统中,动态分区分配是一种重要的操作系统操作方法。

它是指在运行时根据进程的内存需求动态地将系统内存分配给进程,以实现内存资源的高效利用。

动态分区分配操作方法在现代操作系统中被广泛应用,例如Windows、Linux等。

通过合理的动态分区分配策略,可以提升系统的性能和资源利用率。

本文将对动态分区分配操作系统操作方法进行详细介绍和实验步骤的说明。

首先,我们将介绍动态分区分配的背景和意义,包括其在操作系统中的作用和应用场景。

其次,我们将详细讨论实验的具体步骤,包括如何进行动态分区分配操作、如何测试相关的性能指标等。

本文的目标是帮助读者了解动态分区分配操作系统操作方法的基本原理和实践技巧。

同时,通过实际操作和实验验证,读者将能够更好地理解动态分区分配的概念和操作过程,提升对操作系统的理解和应用能力。

在接下来的章节中,我们将分别介绍动态分区分配操作系统操作方法的背景和实验步骤,并给出相应的实例和案例分析。

最后,我们将对实验结果进行总结和展望,探讨动态分区分配操作方法的发展前景和可能的研究方向。

通过本文的阅读和实验操作,读者将能够对动态分区分配操作系统操作方法有一个全面的了解,为进一步研究和应用提供基础和指导。

同时,我们也欢迎读者对本文内容进行补充和扩展,以促进相关领域的进一步发展和应用。

1.2 文章结构文章结构部分的内容可以从以下角度进行描述:文章结构是指整篇文章的组织框架和内容安排。

合理的文章结构可以使读者更好地理解文章的主题和内容,帮助读者快速找到所需信息并形成完整的认识。

本文将按照以下结构进行论述:1. 引言:在引言部分,我们将对动态分区分配操作系统操作方法的背景和意义进行介绍,明确文章的目的和重要性。

2. 正文:正文是文章的核心部分,将分为两个要点进行叙述。

2.1 第一个要点:动态分区分配操作系统操作方法。

首先,我们将对动态分区分配的背景进行介绍,解释其在操作系统中的应用和意义。

动态分区分配算法

动态分区分配算法

计算机操作系统动态分区磁盘调度算法一个好的计算机系统不仅要有足够的存储容量,较高的存取速度和稳定可靠的存储器,而且能够合理的分配和使用这些主存空间。

当用户提出申请主存空间的要求时,存储管理能够按照一定的策略分析主存的使用情况,找出足够的空间分配给申请者;当作业运行完毕,存储管理要回收作业占用的主存空间。

本实验采取可变分区存储管理方法,用常用分区管理算法模拟磁盘管理过程,以加深了解操作系统的存储管理功能。

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"; }。

计算机操作系统实验报告动态分区分配方式的模拟

计算机操作系统实验报告动态分区分配方式的模拟

计算机操作系统实验报告姓名:班级:学号:题目:动态分区分配方式的模拟实习内容简要描述本次实验要完成两部分内容:一是用C语言实现对采用首次适应算法和最佳适应算法的动态分区分配过程ALLOCo和回收过程FREE(),其中空闲分区由空闲分区链来管理,进行分配时,系统优先使用空闲区底端空间。

二是假设初始状态下,可用内存空间为640KBO按照题目要求的作业顺序,以及各个作业分配和回收的内存空间。

分别采用首次适应法和最佳适应法,对内存进行分配和回收,要求每次分配和回收后显示空闲内存分区链的情况。

实验分析算法介绍本次实验通过用C语言进行编程并调试、运行,形象地表现出动态分区的分配方式,直观地展现了首次适应算法和最佳适应算法对内存的释放和回收方式之间的区别。

加深了我们对两种算法优缺点的理解,帮助我们了解一些数据结构和分配算法,进一步加深我们对动态分区存储器管理方式及其实现过程的理解。

主要的问题在于,如何解决两种算法对内存的释放和回收空间的表示。

动态分区分配:又称为可变分区分配,这种分配方式并不事先先将主存划分成一块块的分区,而是在作业进入主存时,根据作业的大小动态地建立分区。

并使分区的大小正好适应作业的需要。

因此系统中分区的大小是可变的,分区的数目也是可变的。

分区分配算法:(两者的空闲块链接方式不冋)①首次适应法:为作业选择分区时总是按地址从高到低搜索,只要找到可以容纳该作业的空白块,就把该空白块分配给该作业。

特点:优先利用内存中底地址部分的空闲分区(将所有空闲区,按其地址递增的顺序链接)②最佳适应算法:接到内存申请时,在空闲块表中找到一个不小于请求的最小空块进行分配;为作业选择分区时总是寻找其大小最接近于作业所要求的存储区域。

特点:用最小空间满足要求(将所有空闲区,按其大小递增的顺序联接成空闲区链)结果分析(思考题解答;错误原因分析)间的分配和回收。

思考题解答:1、首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。

动态分区分配算法实验报告

动态分区分配算法实验报告

操作系统实验报告实验二:动态分区分配算法学生:学号:学院:系别:专业:实验时间:报告时间:一、实验内容编写一个内存动态分区分配模拟程序,模拟内存的分配和回收的完整过程。

一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。

当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。

当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。

主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间的分配和回收。

三、实验原理模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收。

(1)可变分区方式是按作业需要的主存空间大小来分割分区的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。

随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。

例如:为了说明哪些区是空闲的,可以用来装入新作业,必须要有一X 空闲区说明表,格式如下:第一栏第二栏其中,起址——指出一个空闲区的主存起始地址。

长度——指出从起始地址开始的一个连续空闲的长度。

状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区。

(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。

为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。

为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。

动态分区分配算法

动态分区分配算法

动态分区分配算法动态分区分配算法是计算机在处理大型计算问题时分配内存的一种算法。

它由英国计算机科学家考克·拉伦斯(C. Alan Rees)和美国计算机科学家杰弗里·布朗(Geoffrey Brown)于1959年提出,发展到今天,仍然是当前计算机内存管理中应用最为广泛的算法之一。

据统计,它在数据处理和科学计算中应用最为广泛,比例达到90%以上。

动态分区分配算法建立在虚拟存储器系统于单一空间中的理论上,它会将虚拟存储器空间分割成多个区块,即所谓的“分区”,在这些“分区”中每一个“分区”被认为是一个独立的内存块,它可以被视作内存的一个物理分割实体。

确定分区个数以及每个分区的大小,称为分区的方法的决定步骤。

分区的决定步骤有固定分区、可变分区和动态分区等。

固定分区分配法要求在系统安装前确定程序分区的规模,在整个运行期间该规模是不变的,因此片面此法解决不了内存非连续性的问题。

可变分区分配法将内存空间分割成几个大小不等的可变尺寸的分区,这种算法的原理还是以空间的划分为两个分区,它有效解决了内存空间划分的非连续性问题,但受到固定分区的分配量的限制,因此它的可扩大性也有所限制。

动态分区分配算法可以根据运行时不断地选择最终分区的大小,以获得最优的内存分配方案,它扩展了计算机系统中内存空间的使用,同时能够满足多台机器大型程序精确分配内存大小的要求,它可以更好地充分利用计算机系统中的内存。

动态分区分配算法是一种比较强大的算法,它能够根据实际情况提供充分利用空间的储存形式,处理实时物理系统的大型问题,并在很大的程度上提高了工作效率,节约价值,以及满足多台机器大型软件应用程序的需要。

操作系统实验四实验报告动态分区分配算法

操作系统实验四实验报告动态分区分配算法

操作系统实验四【实验题目】:动态分区分配算法【实验学时】: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("DTFQ.txt");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++){inf.get(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;}}//re();}void next_fit(){renew();cout<<"next fit:";int i,j;int m=0,tag=0,count=0;for(i=0;i<work_num;i++){for(j=m;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;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;}}//re();}void best_fit(){renew();cout<<"best fit:";int i,j,k,temp,m;int tag=0,n=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=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;}}//re();}void worst_fit(){renew();cout<<"worst fit:";int i,j,k,temp,m;int tag=0,n=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=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");}实验截图:如有侵权请联系告知删除,感谢你们的配合!。

操作系统实验—动态分区分配算法

操作系统实验—动态分区分配算法

操作系统实验报告实验2 动态分区分配算法报告日期:2016-6-15姓名:学号:班级:任课教师:实验2 动态分区分配算法一、实验内容编写一个内存动态分区分配模拟程序,模拟内存的分配和回收的完整过程。

二、实验目的一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。

当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。

当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。

主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间的分配和回收。

三、实验原理模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收。

(1)可变分区方式是按作业需要的主存空间大小来分割分区的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。

随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。

例如:为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:第一栏 第二栏 M其中,起址——指出一个空闲区的主存起始地址。

长度——指出从起始地址开始的一个连续空闲的长度。

状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区。

(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。

为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。

为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。

实验四内存分配算法

实验四内存分配算法

实验四内存块的申请与释放一.实验目的1.掌握内存动态分区的实现方法。

2.进一步掌握内存块的分配策略。

3.掌握内存块申请与释放的算法与实现。

二.实验内容写一个程序,模拟实现内存的动态分区分配算法。

假设内存大小为100K。

1.分别使用首次适应算法、最佳适应算法分配内存空间。

2.实现对内存空间的释放。

3.显示内存分配情况。

三.实验环境本实验可以在Turbo C环境下实现。

四.实验程序及分析/* 进入程序后可以根据菜单项进入不同的模块 *//* 1. 使用首次适应算法分配空间 *//* 2. 使用最佳适应算法分配空间 *//* 3. 释放一块空间 *//* 4. 显示内存分配情况 *//* 5. 退出系统 *//*--------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <string.h>#define MEMSIZE 100 /*定义内存大小为100*/#define MINSIZE 2 /*分配时如果剩余值小于此值则不再分割*/typedef struct _MemoryInformation{ /*空间分区表结构*/int start; /*起始地址*/int size; /*大小*/char info; /*状态:'f'空闲(FREE); 'u'占用(USED); 'e'表结束(END)*/}MEMINFO;MEMINFO MemList[MEMSIZE];void Display();/*--------------------------------------------------------------*//*函数名:InitAll() *//*功能:初始化所有变量。

动态分区分配算法

动态分区分配算法

动态分区分配算法动态分区分配算法⼀实验内容与要求内容:动态分区分配是根据进程的实际需要,动态地为之分配内存空间,⽽在分配时,须按照⼀定的分配算法,从空闲分区表或空闲分区链中选出⼀分区分配给该作业。

在本实验中运⽤了三种分配算法,分别是1.⾸次适应算法,2.循环⾸次适应算法,3.最佳适应算法。

要求:动态分区算法也称为可变分区分配算法,常见的空闲区查找算法有⾸次适应算法,循环⾸次适应算法,最佳适应算法。

特别注意分区回收时,相邻空闲分区需要合并。

(1)参考操作系统教材理解这3种分配算法以及回收算法。

(2)实现3种分配算法以及回收算法。

(3)已知作业申请内存和释放内存的序列,给出内存的使⽤情况。

(4)作业申请内存和释放内存的序列可以存放在⽂本⽂件中。

(5)设计简单的交互界⾯,演⽰所设计的功能。

(可以使⽤MFC进⾏界⾯的设计)(6)可根据⾃⼰能⼒,在完成以上基本要求后,对程序功能进⾏适当扩充。

⼆、需求分析本次实验通过⽤C语⾔进⾏编程并调试、运⾏,形象地表现出动态分区的分配⽅式,直观地展现了⾸次适应算法和最佳适应算法对内存的释放和回收⽅式之间的区别。

加深了我们对两种算法优缺点的理解,帮助我们了解⼀些数据结构和分配算法,进⼀步加深我们对动态分区存储器管理⽅式及其实现过程的理解。

主要的问题在于,如何解决两种算法对内存的释放和回收空间的表⽰。

动态分区分配:⼜称为可变分区分配,这种分配⽅式并不事先先将主存划分成⼀块块的分区,⽽是在作业进⼊主存时,根据作业的⼤⼩动态地建⽴分区。

并使分区的⼤⼩正好适应作业的需要。

因此系统中分区的⼤⼩是可变的,分区的数⽬也是可变的。

分区分配算法:1.⾸次适应法:为作业选择分区时总是按地址从⾼到低搜索,只要找到可以容纳该作业的空⽩块,就把该空⽩块分配给该作业。

特点:优先利⽤内存中底地址部分的空闲分区 (将所有空闲区,按其地址递增的顺序链接)2.循环⾸次适应算法该算法是由⾸次适应算法演变⽽成,在为进程分配内存空间时,不再是每次都从第⼀个空间开始查找,⽽是从上次找到的空闲分区的下⼀个空闲分区开始查找,直⾄找到第⼀个能满⾜要求的空闲分区,从中划出⼀块与请求⼤⼩相等的内存空间分配给作业,为实现本算法,设置⼀个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到⼀个满⾜要求的分区,则此次内存分配失败。

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

实验四动态分区分配算法实验报告及程序————————————————————————————————作者:————————————————————————————————日期:实验报告四动态分区分配算法班级学号姓名一、实验目的动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。

在本实验中运用了四种分配算法,分别是 1.首次适应算法,2.循环首次适应算法,3.最坏适应算法4.最佳适应算法。

二、实验环境普通的计算机一台,编译环境Microsoft Visual C++ 6.0三、算法思想1.数据结构(1)分区开始地址startaddress(2)分区大小size(3)分区状态state2.功能介绍(1)首次适应算法在首次适应算法中,是从已建立好的数组中顺序查找,直至找到第一个大小能满足要求的空闲分区为止,然后再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空间令开辟一块新的地址,大小为原来的大小减去作业大小,若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(2)循环首次适应算法该算法是由首次适应算法演变而成,在为进程分配内存空间时,不再是每次都从第一个空间开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业,为实现本算法,设置一个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(3)最坏适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最大的空闲分区分配给作业。

(4)最佳适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最小的空闲分区分配给作业。

四、源程序#include <stdio.h>#define L 10typedef struct LNode{int startaddress;int size;int state;}LNode;LNodeP[L]={{0,128,0},{200,256,0},{500,512,0},{1 500,1600,0},{5000,150,0}};int N=5; int f=0;void print(){ int i;printf("起始地址分区状态\n");for(i=0;i<N;i++)printf("%3d %8d %4d\n",P[i].startaddress, P[i].size,P[i].state);}void First(){ int i,l=0,m;printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break; }else{P[N].startaddress=P[i].startaddress+m;P[N].size=P[i].size-m;P[i].size=m;P[i].state=1;l=1; N++;break; } }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void CirFirst(){ int l=0,m,t=0;printf("\n输入请求分配分区的大小:");scanf("%d",&m);while(f<N){ if(P[f].size<m){ f=f+1;if(f%N==0){ f=0;t=1;}continue; }if(P[f].size==m && P[f].state!=1){ P[f].state=1;l=1; f++;break; }if(P[f].size>m && P[f].state!=1){ P[N].startaddress=P[f].startaddress+m;P[N].size=P[f].size-m;P[f].size=m;P[f].state=1;l=1; N++;f++; break; } }if(l==1){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Worst(){int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1; break; }elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]>a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Best(){ int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break;}elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]<a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void main(){ int k=0;printf("动态分区分配算法:");while(k!=5){printf("\n~~~~~~~~主菜单~~~~~~~~~");printf("\n1、首次适应算法\n2、循环首次适应算法");printf("\n3、最坏适应算法\n4、最佳适应算法");printf("\n5、退出\n");printf("请选择算法:");scanf("%d",&k);switch(k){ case 1:printf("\n初始状态为:\n");print();First();continue;case 2:printf("\n初始状态为:\n");print(); CirFirst(); continue; case 3: printf("\n 初始状态为:\n"); print(); Worst(); continue; case 4:printf("\n 初始状态为:\n"); print(); Best(); continue; case 5: break; default:printf("选择错误,请重新选择。

\n"); } } }五、 运行结果运行效果如下所示,首先列出主菜单,如图1所示,初始状态为已定义好的数组,首先采用首次适应算法,输入的分区大小为500,从图2可以看出,第一个满足条件的起始地址为500,分区大小为512,分配后,起始地址为500的状态设为1,将其余的分区令开辟空间存储。

(1)(2)然后采用算法2即循环首次适应算法,在第一次的分配作业大小为1500,则系统就会将地址为1500的分区进行分配,剩余分区令开辟空间,如图3所示;在第二次的分配作业大小为200,依照算法可得,地址为200的分区复合要求,则将其分配给作业,如图4所示。

(3) (4)(5) (6)在算法3中,采用的是最坏适应算法,设分配作业大小为20,由初始状态可知,分区最大且没有被分配的起始地址为5000,大小为150,分配后的状态如图5所示。

在算法4中,采用的是最优适应算法,设分配大小为10,由初始状态可知,分区最小且没有被分配的起始地址为1000,大小为12,分配后的状态如图6所示。

最后选择5,则结束程序的运行,效果如图7所示。

(7)六、实验总结在一开始老师布置这次的实验题目时,自己根本不知道要干什么,因为在上课时对动态分区分配这节内容不是太了解,所以在上机时不知道如何下手,后来,将本章内容反复的看了几遍之后,终于有了自己的思路。

在程序的编写过程中,我并没有按照书上所说的定义了双向链表来实现各种算法的执行,我只简单的运用了结构体数组,通过这种方法比较容易理解与编写,在这几个算法中,只有循环首次适应算法编写起来有点困难,因为涉及到了循环,而其他的算法只运行一遍就能够得出所要的效果,因此在程序中,我使用了一个全局变量来掌控循环以及记录上次运行到的地方,只要理解了算法的主要思想,编写程序就比较容易了。

相关文档
最新文档