实验报告三磁盘存储空间的分配和回收
实习3 磁盘存储空间的分配和回收
实习三磁盘存储空间的分配和回收一、实习题目连续磁盘存储空间的分配和回收。
二、实习目的磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。
用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。
一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。
怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实习使学生掌握磁盘存储空间的分配和回收算法。
三、实习内容模拟磁盘空闲空间的表示方法,以及模拟实现磁盘空间的分配和回收。
四、设计思想1.设计思路(1) 要在磁盘上建立顺序文件时,必须把按序排列的逻辑记录依次存放在磁盘的连续存储空间中。
可假定磁盘初始化时,已把磁盘存储空间划分成若干等长的块(扇区),按柱面号和盘面号的顺序给每一块确定一个编号。
随着文件的建立、删除、磁盘存储空间被分成许多区(每一区包含若干块),有的区存放着文件,而有的区是空闲的。
当要建立顺序文件时必须找到一个合适的空闲区来存放文件记录,当一个文件被删除时,则该文件占用的区应成为空闲区。
为此可用一张空闲区表来记录磁盘存储空间中尚未占用的部分,格式如下:(2) 建立文件时,先查找空闲区表,从状态为“未分配”的表项中找出一个块数能满足要求的区,由起始空闲块号能依次推得可使用的其它块号。
若不需要占用该区的所有块时,则剩余的块仍应为未分配的空闲块,这时要修改起始空闲块号和空闲块数。
若占用了该区的所有块,则相应登记栏中的状态修改成“空表目”。
删除一个文件时,需要考虑空闲块的合并情况。
磁盘存储空间的分配和回收算法类似于主存储器的可变分区方式的分配和回收。
(3) 当找到空闲块后,必须启动磁盘把信息存放到指定的块中,启动磁盘必须给出由三个参数组成的物理地址:盘面号、柱面号和物理记录号(即扇区号)。
存储器管理实验实验报告
存储器管理实验实验报告一、实验目的存储器管理是操作系统的重要组成部分,本次实验的目的在于深入理解存储器管理的基本原理和方法,通过实际操作和观察,掌握存储器分配与回收的算法,以及页面置换算法的实现和性能评估。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验内容与步骤(一)存储器分配与回收算法实现1、首次适应算法(1)原理:从空闲分区链的首地址开始查找,找到第一个满足需求的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态(已分配或空闲)。
当有分配请求时,从链表头部开始遍历,找到第一个大小满足需求的空闲分区。
将该分区进行分割,一部分分配给请求,剩余部分仍作为空闲分区留在链表中。
若找不到满足需求的空闲分区,则返回分配失败。
2、最佳适应算法(1)原理:从空闲分区链中选择与需求大小最接近的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历整个链表,计算每个空闲分区与需求大小的差值。
选择差值最小的空闲分区进行分配,若有多个差值相同且最小的分区,选择其中起始地址最小的分区。
对选中的分区进行分割和处理,与首次适应算法类似。
3、最坏适应算法(1)原理:选择空闲分区链中最大的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历链表,找到最大的空闲分区。
对该分区进行分配和处理。
(二)页面置换算法实现1、先进先出(FIFO)页面置换算法(1)原理:选择在内存中驻留时间最久的页面进行置换。
(2)实现步骤:建立页面访问序列。
为每个页面设置一个进入内存的时间戳。
当发生缺页中断时,选择时间戳最早的页面进行置换。
2、最近最久未使用(LRU)页面置换算法(1)原理:选择最近一段时间内最长时间未被访问的页面进行置换。
磁盘存储空间的分配和回收1doc
磁盘存储空间的分配与回收一.实验内容:模拟实现磁盘空间的分配与回收.二.实验目的:磁盘格式化时,系统把磁盘存储空间分成许多磁道.每个磁道又分成若干个扇区(又叫做块).这些空间就是用来存放用户文件的.当用户的文件不再需要时,就应该删除.把一个文件存放到磁盘上时,可以组织成连续文件,链接文件,索引文件等.因此,磁盘空间的分配方法也有两种,一种是连续空间的分配;一种是不连续空间的分配(又叫动态分配).如何充分有效的利用磁盘空间,是操作系统应解决的重要课题之一.通过本实验,使学生对磁盘空间的分配与回收有一个较深入的理解.三.实验题目:1.用位示图管理磁盘空间,设计一个申请与申请与回收一个或几个磁盘块的分配与回收算法. 要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理过程.提示:(1)磁盘的位示图用若干个字节构成,每一位对应一个磁盘块.”1表示占用,”0”表示空闲.为了简单,假定现有一个磁盘组,共40个柱面.每个柱面四个磁道,每个磁道又划分成4个物理记录.假定字长为16位,其位示图如下图所示:(2)申请一个磁盘块时,由分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出它的柱面号,磁道号和扇区号).由位示图计算磁盘的相对块号的公式如下:相对块号=字号*16+位号之后再将相对块号转换成磁盘的物理地址:柱面号=相对块号/16的商,也即柱面号=字号磁道号=(相对块号/16的余数)/4的商,也即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,也即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置”0”.计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号*16+磁道号*4+物理块号再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号位号=磁道号*物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配.将分配相对块号返回用户,并将相对块号转换成磁盘绝对地址给以显示和系统各表和用户已分配的情况进行显示. (5)分配框图如图:(6)设计一个回收算法,将上述已分配的给用户的各盘块释放,并显示系统各表.收获与体会:通过进行操作系统的上机实验,我们从中可以更深刻的理解书本上的内容,以及操作系统中的一些最基本的原理.同时这也是对我们C语言的能力的一个锻炼和提高.在这几次上机实验中,我们还接触到了Linux系统,学会了该系统的最基本的使用方法,譬如挂载软盘,编译源程序等等,这也为我们以后更好的掌握该系统打下了很好的基础.但是从这次实践中,我们也感觉到自己在很多方面还存在不足,比如对某些函数的应用还不熟练,希望以后能多练习多实践,这样才能真正提高自己对课程的理解.附源程序:/*本程序顺序分配空间,所以运行后开始几个数字都是'1'*/#include<string.h>#include<stdio.h>#define ROW 12#define COLUMN 16#define AREA 192int a[ROW][COLUMN]={1,1,1,0,0,1,0,1,1,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,0,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,1,1,0,1,0,1,1,0,};int b[ROW][COLUMN]={0};int c[AREA][3]={0};int static y;int input(int p);void distribute(int p);void callbackall(void);void callbackpointed(int n);main(){static int i,j,n,p;printf("**********************************");printf("********designed by weiwei********");printf("**********************************");printf("The distribution and callback of disk space.\n");printf("press any key to display the status of the disk.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}printf("Press any key to apply space from disk.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){if(a[i][j])continue;else{c[p][0]=p+1;c[p][1]=i*16+j;p++;}}}y=p;printf("There are %d blocks to use.",p);distribute(n);printf("\nThe next step is callbacking the space,press any key.\n");printf("You have these choices:\n");printf("1:\t Free all the disk blocks you apply just now\n");printf("2:\t Free a disk block that is destined \n");printf("3:\t Exit\n");i=input(3);while(i){switch(i){case 1:callbackall(n);break;case 2:callbackpointed(n);printf("\n\nYou stil have these choices:\n");printf("1:\t free all the disk blocks you apply just now\n");printf("2:\t free a pointed disk block\n");printf("3:\t esc\n");printf("Please make a choice:\n");i=input(3);break;case 3:exit(1);break;}}}int input(int p){static int k;scanf("%d",&k);if(k<=0||k>p){printf("Wrong input!!!!please enter a number that is greater than 0 and lessthan %d:\n",p);input(p);}return k;}void distribute(int x){static int i,j,k,p,m,n,q;printf("Please enter which disk block do you want to free from.\n");k=input(y);/*输入开始释放的量*/printf("Please enter how many disk blocks do you want to free.\n");printf("You must enssure the data is right\n");j=input(y);/*要释放多少个*/if(k+j>y){printf("Wrong input!!! The blocks you want to distribute is beyond the mark.\n ");printf("Please enter another legal number to be the first one and the amount:\n\n ");distribute(y);}else{for(i=k;i<k+j;i++){q=c[i-1][1];m=q/16;n=q%16;p=m*16+n;a[m][n]=1;b[m][n]=1;printf("%d:\t related block No. %d;cylinder No. %d;track No. %d;physic block No. %d\n",i,p,m,n/4,n%4);}printf("Press any key to compare this matrix to the last one\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}}void callbackall(int n){int i,j,m;for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){if(!b[i][j])continue;else{a[i][j]=0;}}}printf("press any key to compare this matrix to the first one.\n");getchar();printf("you can see it recruits:\n");for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}void callbackpointed(int n){static int i,k,q,m,j,p;printf("Please enter which disk block do you want to free from.\n");k=input(n);/*输入开始释放的量*/printf("Please enter how many disk blocks do you want to free.\n");printf("You must enssure the data is right\n");j=input(n);/*要释放多少个*/if(k+j>n+1){printf("Wrong input!!! The blocks you want to free is beyond the mark.\n ");printf("Please enter another legal number to be the first one and the amount:\n\n ");callbackpointed(n);}else{for(i=k;i<k+j;i++){q=c[i-1][1];m=q/16;p=q%16;a[m][p]=0;/*c[i-1][3]=1;c[k-1][3]=1表明已经被释放了*/}printf("The pointed disk block has been freeed,press any key to check the result.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}}。
操作系统实验报告-可变分区存储管理方式的内存分配回收
实验三可变分区存储管理方式的内存分配回收一.实验目的(1)深入了解可变分区存储管理方式的内存分配回收的实现。
二.实验内容编写程序完成可变分区存储管理方式的内存分配回收,要求有内存空间分配表,并采用最优适应算法完成内存的分配与回收。
三.实验原理在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。
为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。
在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。
这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。
当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表中,若有相邻空闲区再将其连接后登记。
可变分区的回收算法较为复杂,当一个作业撤离时,可分为4种情况:其临近都有作业(A和B),其一边有作业(A或B),其两边均为空闲区。
尤其重要的是,在程序中利用“new类型T(初值列表)”申请分配用于存放T类型数据的内存空间,利用“delete指针名”释放指针所指向的内存空间。
四.实验部分源程序#include <iostream>using namespace std;typedef struct SNode { // Space Nodeint start,end; // 起始,结束int length; // 长度大小struct SNode *next; // 指向下一结点的指针}* SP;SP Head=(SP)malloc(sizeof(SNode)); // 全局变量,内存空间头结void DispSpace() { // 显示内存空间分配情况SP p=Head->next;cout<<"\n 空闲区说明表\n"<<"---地址--长度---\n";while (p){cout<<" "<<p->start<<" "<<p->length<<endl;p=p->next;}cout<<"----------------\n";}void Initial() { // 初始化说明表SP p,q;p=(SP)malloc(sizeof(SNode));q=(SP)malloc(sizeof(SNode));p->start=14; p->length=12; p->end=26;q->start=32; q->length=96; q->end=128; // 指导书上的作业分配Head->next=p; // 与头结点连接p->next=q;q->next=NULL;DispSpace();}void Allocation(int len) { // 分配内存给新作业SP p=Head->next,q;while (p){if (p->length < len)p=p->next;else if (p->length > len){p->start=p->start+len;p->length=p->length-len;cout<<"分配成功!\n";DispSpace(); return;}else{//当两者长度相等q=p->next;p->next=q->next;cout<<"分配成功!\n";DispSpace(); return;}}cout<<"分配失败!\n";DispSpace(); return;}void CallBack(int sta,int len) { // 回收内存SP p=Head,q=p->next,r; // 开始地址和长度p->end=0;int en=sta+len;while (q) {if (sta == 0) { // 初始地址为0if (en == q->start) { // 正好回收q->start=0;q->length=q->end;return;}else {r=(SP)malloc(sizeof(SNode));r->start=sta; r->length=len; r->end=en;p->next=r;r->next=q;return;}}else if ((p->end < sta) && (q->start > en)) { // 上邻区r=(SP)malloc(sizeof(SNode));r->start=sta; r->length=len; r->end=en;p->next=r;r->next=q;return;}else if ((p->end < sta) && (q->start == en)) { // 邻区相接q->start=sta;q->length=q->end-sta;return;}else if ((p->end == sta) && (q->start < en)) { // 下邻区p->end=en;p->length=en-p->start;return;}else if (p->end==sta && q->start==en) { // 邻区相接p->end=q->end;p->length=p->end-p->start;p->next=q->next;return;}else {p=p->next;q=q->next;}}}void main() {Initial();cout<<"现在分配大小为6K 的作业4 申请装入主存: ";Allocation(6); // 分配时参数只有长度//--------指导书测试数据演示----------cout<<"现回收作业 3 (起址10,长度4)\n";CallBack(10,4);DispSpace();cout<<"现回收作业 2 (起址26,长度6)\n";CallBack(26,6);DispSpace();//---------------演示结束-------------system("pause");}五.实验结果与体会我的体会:下面红色部分是赠送的总结计划,不需要的可以下载后编辑删除!2014年工作总结及2015年工作计划(精选)XX年,我工区安全生产工作始终坚持“安全第一,预防为主,综合治理”的方针,以落实安全生产责任制为核心,积极开展安全生产大检查、事故隐患整改、安全生产宣传教育以及安全生产专项整治等活动,一年来,在工区全员的共同努力下,工区安全生产局面良好,总体安全生产形势持续稳定并更加牢固可靠。
内存的分配和回收分区链实验报告按照这个内容来完成
一、实验目的理解分区式存储管理的基本原理,熟悉分区分配和回收算法。
即理解在不同的存储管理方式下,如何实现主存空间的分配与回收;并掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
二、设备与环境1. 硬件设备:PC机一台2. 软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如VC \VC++\Java 等编程语言环境。
三、实验原理实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。
A、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。
(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。
B、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。
内存分配回收实验报告
一、实验目的通过本次实验,加深对内存分配与回收机制的理解,掌握内存分配算法和回收策略,并能够运用所学知识解决实际内存管理问题。
二、实验内容1. 确定内存空间分配表;2. 采用首次适应算法实现内存分配;3. 采用最佳适应算法实现内存分配;4. 采用最坏适应算法实现内存分配;5. 实现内存回收功能;6. 对比分析不同内存分配算法的优缺点。
三、实验步骤1. 创建一个内存空间模拟程序,用于演示内存分配与回收过程;2. 定义内存空间分配表,记录内存块的起始地址、大小和状态(空闲或占用);3. 实现首次适应算法,在内存空间分配表中查找第一个满足条件的空闲内存块,分配给请求者;4. 实现最佳适应算法,在内存空间分配表中查找最接近请求大小的空闲内存块,分配给请求者;5. 实现最坏适应算法,在内存空间分配表中查找最大的空闲内存块,分配给请求者;6. 实现内存回收功能,当内存块释放时,将其状态更新为空闲,并合并相邻的空闲内存块;7. 对比分析不同内存分配算法的优缺点,包括分配时间、内存碎片和内存利用率等方面。
四、实验结果与分析1. 首次适应算法:该算法按照内存空间分配表的顺序查找空闲内存块,优点是分配速度快,缺点是容易产生内存碎片,且内存利用率较低;2. 最佳适应算法:该算法查找最接近请求大小的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多;3. 最坏适应算法:该算法查找最大的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多。
五、实验结论通过本次实验,我们掌握了内存分配与回收的基本原理和算法,了解了不同内存分配算法的优缺点。
在实际应用中,我们需要根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
六、实验心得1. 内存分配与回收是计算机系统中重要的组成部分,对系统性能有着重要影响;2. 熟练掌握内存分配算法和回收策略,有助于解决实际内存管理问题;3. 在实际应用中,应根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
操作系统实验报告三存储器管理实验
操作系统实验报告三存储器管理实验操作系统实验报告三:存储器管理实验一、实验目的本次存储器管理实验的主要目的是深入理解操作系统中存储器管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收的算法,以及页面置换算法的工作过程和性能特点,从而提高对操作系统资源管理的认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验内容1、内存分配与回收算法实现首次适应算法(First Fit)最佳适应算法(Best Fit)最坏适应算法(Worst Fit)2、页面置换算法模拟先进先出页面置换算法(FIFO)最近最久未使用页面置换算法(LRU)时钟页面置换算法(Clock)四、实验原理1、内存分配与回收算法首次适应算法:从内存的起始位置开始,依次查找空闲分区,将第一个能够满足需求的空闲分区分配给进程。
最佳适应算法:在所有空闲分区中,选择能够满足需求且大小最小的空闲分区进行分配。
最坏适应算法:选择空闲分区中最大的分区进行分配。
2、页面置换算法先进先出页面置换算法:选择最早进入内存的页面进行置换。
最近最久未使用页面置换算法:选择最近最长时间未被访问的页面进行置换。
时钟页面置换算法:给每个页面设置一个访问位,在页面置换时,从指针指向的页面开始扫描,选择第一个访问位为0 的页面进行置换。
五、实验步骤1、内存分配与回收算法实现定义内存分区结构体,包括分区起始地址、大小、是否已分配等信息。
实现首次适应算法、最佳适应算法和最坏适应算法的函数。
编写测试程序,创建多个进程,并使用不同的算法为其分配内存,观察内存分配情况和空闲分区的变化。
2、页面置换算法模拟定义页面结构体,包括页面号、访问位等信息。
实现先进先出页面置换算法、最近最久未使用页面置换算法和时钟页面置换算法的函数。
编写测试程序,模拟页面的调入和调出过程,计算不同算法下的缺页率,比较算法的性能。
操作系统-内存分配与回收实验报告
操作系统-内存分配与回收实验报告本次实验是关于内存管理的实验,主要涉及内存分配和回收的操作。
本文将对实验过程和结果进行详细介绍。
1. 实验目的本次实验的主要目的是熟悉内存管理的基本原理和机制,掌握内存分配和回收的方法,并且实现一个简单的内存管理器。
2. 实验原理内存管理是操作系统的重要组成部分,主要负责管理计算机的内存资源,并且协调进程对内存的访问。
在计算机工作过程中,内存扮演着重要的角色,因此内存管理的效率和稳定性对计算机的性能和稳定性有着重要影响。
内存管理包括内存分配和回收两个方面。
内存分配是指为进程分配空闲的内存空间,以便程序可以执行;内存回收是指将已经使用完成的内存空间还回给系统,以便其他进程使用。
3. 实验步骤为了实现一个简单的内存管理器,我们需要进行以下步骤:(1)定义内存块结构体首先,我们需要定义一个内存块结构体,用于描述内存块的基本信息。
内存块结构体可以包含以下信息:· 内存块的起始地址· 内存块是否被分配下面是一个内存块结构体定义的示例代码:typedef struct mem_block{void *start_address; // 内存块的起始地址size_t size; // 内存块的大小bool is_allocated; // 内存块是否已经分配}MemBlock;(3)实现内存分配函数现在,我们可以开始实现内存分配函数了。
内存分配函数需要完成以下工作:· 在内存管理器中寻找一个合适的内存块void *mem_alloc(MemManager *manager, size_t size){MemBlock *p = manager->block_list;while(p){if(p->size >= size && !p->is_allocated){p->is_allocated = true;return p->start_address;}p = p->next;}return NULL;}· 找到该内存块所在的位置· 将该内存块标记为未分配状态4. 实验结果本次实验实现了一个简单的内存管理器,通过该内存管理器可以实现内存分配和回收的操作。
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号: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表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。
主存空间的分配与及回收实验报告
主存空间的分配与及回收实验报告一、实验目的:1.了解主存空间的分配与回收的基本原理;2.掌握主存空间分配与回收的常用算法;3.学会利用实验方法验证主存空间分配与回收的效果。
二、实验原理:1.主存空间的分配:静态分配是指在程序编译时,为程序分配固定大小的存储空间。
这种分配方式的缺点是无法适应不同大小的程序需求,造成了存储空间的浪费。
动态分配是指在程序运行时,根据需要动态分配存储空间。
常见的动态分配方式有两种:堆和栈。
堆是由程序员自行分配和释放的,栈是由系统自动分配和释放的。
动态分配的优点是能够根据需要分配合适的存储空间,减少了空间的浪费。
2.主存空间的回收:常见的回收方式有两种:手动回收和自动回收。
手动回收是指由程序员手动释放不再需要的存储空间。
这种回收方式的优点是能够具体控制存储空间的回收时间,但缺点是容易出现程序员忘记手动回收的情况,导致存储空间的浪费。
自动回收是指由系统自动回收不再需要的存储空间。
系统根据程序的运行情况自动判断哪些存储空间可以回收,并进行回收操作。
自动回收的优点是减少了程序员的工作量,保证存储空间的合理利用,但缺点是可能会出现不准确的判断,导致存储空间的泄漏。
三、实验步骤:本实验以C语言为例,通过编写一个简单的程序,模拟主存空间的分配与回收过程。
1.编写程序代码:#include <stdio.h>#include <stdlib.h>int maiint *p;p = (int *)malloc(sizeof(int) * 10);if (p == NULL)printf("内存分配失败!\n");exit(1);}int i;for (i = 0; i < 10; i++)p[i]=i*10;}for (i = 0; i < 10; i++)printf("%d ", p[i]);}printf("\n");free(p);return 0;2.编译并运行程序:在命令行中输入以下命令,编译并运行程序:gcc -o memory_allocation memory_allocation.c./memory_allocation3.实验结果分析:程序运行后,首先使用malloc函数分配了一块大小为sizeof(int)* 10的存储空间,用于存储10个整数。
内存的分配与回收实验报告(最先适应法)
代码实现如下:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define n 64 //定义内存的大小int a[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数char name[n];//已分配内存的名称(字符类型)typedef struct linknode{char pid;int start;int length;struct linknode *left,*right;}de_node; //进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node *head1,*head2=NULL;struct linknode* creat()//创建一个进程节点{int len,flag1=1;//用于表示进程是否可以创建char id;struct linknode* p;p = (de_node *)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程if (p==NULL) //p为空,说明系统没有可用内存用于创建此模拟进程{ printf("系统没有足够的内存可供使用!\n");//输出return(NULL);//返回空指针}printf("请输入进程id(字符类型)和长度:");//为进程输入id和分配的长度scanf("%c %d",&id,&len);fflush(stdin);//清除输入缓存if((id>='a'&&id<='z'||id>='A'&&id<='Z')&&(len>0)){for(int i=0;i<count;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf("此名称进程已存在!!");flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);return NULL;}if(len==0) {//如果输入要分配的进程长度为0,释放p,返回空指针printf("输入长度为0!\n");free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p->pid=id; //idp->start=0; //初始开始内存位置,在以后会修改p->length=len;//长度p->left=NULL;//左指针p->right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else {printf("输入进程格式有误\n");free(p);return (NULL);}}//分配内存空间void distribute(de_node *p){ de_node *q=head1,*temp;int flag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q->length>=p->length) {p->start=q->start;//把进程的内存开始地址指向内存的可用开始地址处q->start+=p->length;//可用地址起始改变q->length-=p->length;//可用内存长度修改for(int i=p->start;i<p->start+p->length;i++)//将已分配的内存空间全部置1 a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q->length==0&&q->right!=q) { if(q==head1)//如果第一个满足,修改头指针指向head1=q->right;q->left->right=q->right;q->right->left=q->left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q->right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf("没有满足的内存!\n");count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{ head2=p;//让头指针指向第一个进程p->left=p;//双向队列第一个左右指针都指向自己p->right=p;//双向队列第一个左右指针都指向自己}else if(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向head2=p;//让头指针指向p指向的进程p->left=temp->left;//p进程左边为原来第一个的左边p->right=temp;//p进程右边指向第一个temp->left->right=p;//原来第一个的左边为ptemp->left=p;//原来第一个的左边的进程为p}}}//对进程的回收void reclaim(){ char id;int flag=0;de_node *q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{ printf("已没有进程!\n");}else {//已分配内存队列如果不为空printf("输入要回收的进程id:");//输入要回收进程的idscanf("%c",&id);fflush(stdin);for(int i=0;i<count;i++)//双重循环把要回收的进程找出来,并把记录的id去掉if(name[i]==id){//判断当前的进程是否满足要求for(int j=i;j<count;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q->pid==id&&q->right==q&&head2==q){ head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q->pid==id){//如果找到if(q==head2)head2=q->right;q->left->right=q->right;//修改指针指向q->right->left=q->left;flag=1;break;}else q=q->right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0) printf("没有此进程号!!!\n");//没有找到满足的进程if(flag==1){//表示找到了for(int i=q->start;i<q->start+q->length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q->start>p->start&&p->right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p->right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去q->left=p->left;//修改指针的指向q->right=p;p->left->right=q;p->left=q;if(q->start+q->length==p->start)//可以与后面合并的情况{ q->length+=p->length;//修改指针的指向p->right->left=q;q->right=p->right;free(p);}if(q->left->start+q->left->length==q->start)//可以与前面合并的情况{ q->left->length+=q->length;//修改指针的指向q->left->right=q->right;q->right->left=q->left;free(q);}}}}//打印输出void print(){ de_node *q=head2,*p=head1;if(count==0)printf("没有进程占有内存。
内存的分配与回收实验报告
内存的分配与回收实验报告实验目的:了解计算机内存分配与回收的原理及实现方式,掌握最先适应算法的具体实现,加深对内存管理的理解。
实验原理:内存是计算机系统中的关键组成部分之一,它负责存储程序运行所需的数据和指令。
为了有效管理内存,将其划分为若干个固定大小的单元,称为分配单元。
内存分配与回收的基本原则是尽量高效地利用内存空间。
最先适应算法是一种常用的内存分配算法,它的基本思想是按照内存地址从小到大的顺序,依次寻找满足分配要求的第一个空闲分区。
因为每次分配都是从低地址开始,所以能够尽量填满被回收后的可用内存空间。
实验步骤:1.定义内存块的数据结构,包括起始地址、大小、状态等信息。
2.初始化内存,划分出若干个固定大小的内存块。
3.从给定的进程请求中获取进程需要的内存大小。
4.遍历内存块列表,寻找第一个满足分配要求的空闲分区,即大小大于等于进程需求的分区。
5.如果找到了满足要求的分区,则将其划分为两个分区,一个用于分配给进程,一个作为剩余的空闲分区。
6.更新内存块列表,记录分配给进程的内存块。
7.如果没有找到满足要求的分区,则返回分配失败的信息。
8.进程完成运行后,将其占用的内存块标记为空闲,并进行合并操作,合并相邻的空闲分区。
9.更新内存块列表,记录回收的内存块。
10.重复步骤3至步骤9,直到完成所有的进程请求。
实验结果:经过多次实验,使用最先适应算法进行内存分配与回收,可以有效地利用内存空间,提高内存利用率。
实验总结:通过本次实验,我深入理解了最先适应算法的实现原理和逻辑流程。
在实际的内存管理中,我们需要根据实际情况选择合适的内存分配策略,以避免出现内存碎片和浪费现象。
同时,回收后的内存块需要及时进行合并操作,以提高内存的利用率。
实验过程中还发现,在有大量并发的情况下,最先适应算法可能会产生较多的内存碎片,影响内存的使用效率,因此需要根据实际情况选择其他适合的内存分配算法。
总之,通过这次实验,我对内存分配与回收有了更深入的理解,对内存管理算法的选择和优化也更加清晰,为以后的实际应用打下了基础。
实验三 存储器的分配与回收算法实现(二维数组)教学提纲
实验三存储器的分配与回收算法实现(二维数组)实验三存储器的分配与回收算法◆实验名称:存储器的分配与回收算法实验◆仪器、设备:计算机◆参考资料:操作系统实验指导书◆实验目的:设计一个存储器的分配与回收算法管理方案,并编写模拟程序实现。
◆实验内容:1. 模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。
2. 采用最先适应法、最佳适应法、最坏适应法分配主存空间。
3. 当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。
若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。
4. 当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。
5. 运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。
◆实验要求:1.详细描述实验设计思想、程序结构及各模块设计思路;2.详细描述程序所用数据结构及算法;3.明确给出测试用例和实验结果;4.为增加程序可读性,在程序中进行适当注释说明;5.认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;6.实验报告撰写要求结构清晰、描述准确逻辑性强;实验过程中,同学之间可以进行讨论互相提高,但绝对禁止抄袭。
◆实验过程记录(源程序、测试用例、测试结果及心得体会等实验代码如下:#include <iostream.h>int work[10][2]; //作业名字大小int idle[10][2]; //空闲区大小地址int free[10][3]; //已分配区域的名字地址大小int num=0,b=1,d,ch1,ch2;void init(){idle[0][0]=1;idle[0][1]=100;free[0][0]=0;free[1][1]=0;free[1][2]=0;work[0][0]=0;work[0][1]=0;for(int i=1;i <=9;i++){ //初始化数组idle[i][0]=0;idle[i][1]=0;free[i][0]=0;free[i][1]=0;free[i][2]=0;work[i][0]=0;work[i][1]=0;}}void jishu(){ //求空闲单元数for(int i=0;i <9;i++)if(idle[i][1]!=0)num++;}void jishu1(){ //求作业数for(int i=0;i <9;i++)if(work[i][1]!=0)b++;}void zuixian(){ //最先适应法jishu();for(int i=0;i <num;i++){for(int j=i;j <num-i-1;j++){if(idle[j][0]>idle[j+1][0]){int temp=idle[j][0];idle[j][0]=idle[j+1][0];idle[j+1][0]=temp;temp=idle[j][1];idle[j][1]=idle[j+1][1]; idle[j+1][1]=temp;}}}}void zuijia(){ //最佳适应法num=0;jishu();for(int i=0;i <num;i++){for(int j=i;j <num-i-1;j++){ if(idle[j][1]>idle[j+1][1]){ int temp=idle[j][0];idle[j][0]=idle[j+1][0];idle[j+1][0]=temp;temp=idle[j][1];idle[j][1]=idle[j+1][1];idle[j+1][1]=temp;}}}}void zuihuai(){ //最坏适应法 num=0;jishu();for(int i=0;i <num;i++){for(int j=i;j <num-i-1;j++){ if(idle[j][1] <idle[j+1][1]){ int temp=idle[j][0];idle[j][0]=idle[j+1][0]; idle[j+1][0]=temp;temp=idle[j][1];idle[j][1]=idle[j+1][1]; idle[j+1][1]=temp;}}}}void huishou(int name){ //回收进程函数num=0;b=0;jishu();jishu1();int c=-1;for(int k=0;k <=b;k++){if(free[k][0]==name){c=k;break;}}if(c==-1)cout <<"要回收的作业不存在!" <<endl;else{for(int i=0;i <num;i++){ //将空闲单元排序{不包括新回收的} for(int j=i;j <num-i-1;j++){if(idle[j][0]>idle[j+1][0]){int temp=idle[j][0];idle[j][0]=idle[j+1][0];idle[j+1][0]=temp;temp=idle[j][1];idle[j][1]=idle[j+1][1];idle[j+1][1]=temp;}}}for(int q=0;q <num;q++){ //将空单元排序{包括新回收的}if(free[c][1] <=idle[q][0]){for(int j=num;j>=q;j--){idle[j+1][0]=idle[j][0];idle[j+1][1]=idle[j][1];}idle[j][0]=free[c][1];idle[j][1]=free[c][2];b++;if(idle[j+1][0]==idle[j][0]+idle[j][1]){idle[j][1]=idle[j][1]+idle[j+1][1];for(int m=j+1;m <=num;m++){ idle[m][0]=idle[m+1][0];idle[m][1]=idle[m+1][1];}idle[m][0]=0;idle[m][1]=0;b--;}if(idle[j-1][0]==idle[j][0]){idle[j-1][1]=idle[j-1][1]+idle[j][1];for(int n=j;j <=num;j++){idle[n][0]=idle[n+1][0];idle[n][1]=idle[n+1][1];}idle[n][0]=0;idle[n][1]=0;b--;}break;}}if(ch2==1)zuixian();if(ch2==2)zuijia();if(ch2==3)zuihuai();for(int p=c;c <b-1;c++){free[c][0]=free[c+1][0];free[c][1]=free[c+1][1];free[c][2]=free[c+1][2];work[c][0]=work[c+1][0];work[c][1]=work[c+1][1];}cout<<"该进程已被成功回收!"<<endl;}}void fp(){int tag=0; //判断空闲区与请求区大小num=0;b=0;jishu();jishu1();for(int j=0;j <num;j++){if(work[b][1] <idle[j][1]){free[b][0]=work[b][0];free[b][1]=idle[j][0];free[b][2]=work[b][1];idle[j][0]=idle[j][0]+work[b][1];idle[j][1]=idle[j][1]-work[b][1];tag=1;break;}else if(work[b][1]==idle[j][1]){free[b][0]=work[b][0];free[b][1]=idle[j][0];free[b][2]=work[b][1];tag=1;for(int i=j;i <=num-1;i++){idle[i][0]=idle[i+1][0];idle[i][1]=idle[i+1][1];}break;}else tag=0;}if(tag==0)cout <<"作业过大没有足够存储空间!" <<endl;}void print(){num=0;b=1;jishu();jishu1();cout <<"已分配表为:" <<endl;for(int i=0;i <=b;i++)if(free[i][2]!=0)cout <<"作业名:" <<free[i][0] <<" 内存起始地址:" <<free[i][1] <<" 占用内存空间:" <<free[i][2] <<endl;cout <<endl;cout <<"空闲区表为:" <<endl;for(int j=0;j <num;j++)if(idle[j][1]!=0)cout <<"起始地址:" <<idle[j][0] <<" 连续内存空间:" <<idle[j][1] <<endl; cout <<endl;}void main(){ //主函数运行上面定义的函数init();int n;cout <<"1.分配空间;2.回收空间;" <<endl;cin>>ch1;cout <<endl;cout <<"1.最先适应法;2.最佳适应法;3.最坏适应法;" <<endl;cin>>ch2;cout <<endl;if(ch1==1){cout <<"请输入要分配内存的作业名及占用内存大小:";cin>>work[b][0]>>work[b][1];cout <<endl;if(ch2==1){zuixian();fp();}else if(ch2==2){zuijia();fp();}else if(ch2==3){zuihuai();fp();}print();}cout <<"输入要回收的作业名:" <<endl;cin>>n;huishou(n);}实验截图:成功回收时:回收失败时:实验体会:本次实验的难度较大,尤其是回收进程,主要编写几个算法和回收程序,最佳,最优,最坏算法和回收算法,我用的是数组,有工作数组,空闲数组,已分配数组。
磁盘存储空间的分配和回收
真习六磁盘保存空间的调配战回支之阳早格格创做一、真习真质模拟磁盘空忙空间的表示要领,以及模拟真止磁盘空间的调配战回支.二、真习手段磁盘初初化时把磁盘保存空间分成许多块(扇区),那些空间不妨被多个用户共享.用户做业正在真止功夫时常要正在磁盘上建坐文献或者把已经建坐正在磁盘上的文献删去,那便波及到磁盘保存空间的调配战回支.一个文献存搁到磁盘上,不妨构造成程序文献(连绝文献)、链交文献(串联文献)、索引文献等,果此,磁盘保存空间的调配有二种办法,一种是调配连绝的保存空间,另一种是不妨调配不连绝的保存空间.何如灵验天管造磁盘保存空间是支配系统应办理的一个要害问题,通过原真习使教死掌握磁盘保存空间的调配战回支算法.三、真习题目原真习模拟三种磁盘保存空间的管造要领.第一题:连绝的磁盘保存空间的调配战回支.[提示]:(1) 要正在磁盘上建坐程序文献时,必须把逆次排列的逻辑记录依次存搁正在磁盘的连绝保存空间中.可假定磁盘初初化时,已把磁盘保存空间区分成若搞等少的块(扇区),按柱里号战盘里号的程序给每一齐决定一个编号.随着文献的建坐、简略、磁盘保存空间被分成许多区(每一区包罗若搞块),有的区存搁着文献,而有的区是空忙的.当要建坐程序文献时必须找到一个符合的空忙区去存搁文献记录,当一个文献被简略时,则该文献占用的区应成为空忙区.为此可用一弛空忙区表去记录磁盘保存空间中尚已占用的部分,要领如下:(2) 要建坐文献时,先查找空忙区表,从状态为“已调配”的备案栏目中找出一个块数能谦脚央供的区,由起初空忙块号能依次推得可使用的其余块号.若不需要占用该区的所有块时,则结余的块仍应为已调配的空忙块,那时要建改起初空忙块号战空忙块数.若占用了该区的所有块,则相映备案栏中的状态建改成“空表目”.简略一个文献时,从空忙区表中找一个状态为“空表目”的备案栏目,把送还的起初块号战块数挖进对付应的位子.磁盘保存空间的调配战回支算法类似于主保存器的可变分区办法的调配战回支.共教们可参照真习四的第一题.(3) 当找到空忙块后,必须开用磁盘把疑息存搁到指定的块中,开用磁盘必须给出由三个参数组成的物理天点:柱里号、磁讲号战物理记录号.故必须把找到的空忙块号换算成磁盘的物理天点.为了缩小移臂次数,磁盘上的疑息按柱里上各磁讲程序存搁.现假定一个盘组公有200个柱里,(编号0-199)每个柱里有20个磁讲(编号0-19,共一柱里上的各磁讲分散正在各盘里上,故磁讲号即盘里号.),每个磁讲被分成等少的6个物理记录(编号0-5,每个盘里被分成若搞个扇区,故每个磁讲上的物理记录号即为对付应的扇区号.).那么,空忙块号与磁盘物理天点的对付应闭系如下:假设 , }则 = m }] (4) 磁盘上的起初天点战逻辑记录个数,假定每个逻辑记录占磁盘上的一齐,则可推算出送还后的起初空忙块号战块数,备案到空忙区表中.换算闭系如下:起初空忙块号=(柱里号´20+磁讲号)´6+物理记录号 空忙块数=逻辑记录数(5) 请安排磁盘保存空间的调配战回支步调,央供把调配到的空忙块变换成磁盘物理天点,把送还的磁盘空间变换成空忙块号.假定空忙区表的初值如提示(1)中指出,现有一文献要占用10块,运止您所安排的调配步调,隐现或者挨印调配后的空忙区表以及调配到的磁盘空间的起初物理天点.而后,有一文献被简略,它占用的磁盘空间为:1号柱里2号磁讲,0号物理记录开初的4块,运止您所安排的回支步调,隐现或者挨印回支后的空忙区表.第二题:用位示图管造磁盘保存空间 [提示]:(1) 为了普及磁盘保存空间的利用率,可正在磁盘上构造成链交文献、索引文献,那类文献不妨把逻辑记录存搁正在不连绝的保存空间.为了表示哪些磁盘空间已被占用,哪些磁盘空间是空忙的,可用位示图去指出.位示图由若搞字节形成,每一位与磁盘上的一齐对付应,“1”状态表示相映块已占用,“0”状态表示该块为空忙.位示图的形式与真习四中的位示图一般,但是要注意,对付于主保存空间战磁盘保存空间该当用分歧的位示图去管造,绝不可混用.(2) 申请一齐磁盘空间时,由调配步调查位示图,找出一个为“0”的位,估计出那一位对付应块的磁盘物理天点,且把该位子成占用状态“1”.假设目前有一个盘组共80个柱里,每个柱里有二个磁讲,每个磁讲分成4个物理记录.那么,当正在位示图中找到某一字节的某一位为“0”时,那个空忙块对付应的磁盘物理天点为:柱里号=字节号] }(3) 理天点估计出送还块正在位示图中的对付应位,把该位子成“0”.依照(2)中假设的盘组,送还块正在位示图中的位子估计如下:字节号=柱里号 位数=磁讲号´4+物理记录号(4) 安排申请一齐磁盘空间战送还一齐磁盘空间的步调.央供能隐现或者挨印步调运止前战运止后的位示图;调配时把调配到的磁盘空间的物理天点隐现或者挨印出去,送还时把送还块对付应于位示图的字节号战位数隐现或者挨印出去.(5) 假定已犹如表6-1的磁盘空间被占用了,目前要申请五块磁盘空间,运止调配步调,按(4)中央供隐现或者挨印运止的截止.而后再送还如表6-2的空间,运止回支步调,按(4)中的央供隐现或者挨印运止截止.表6-1表6-2第三题:模拟UNIX系统的空忙块成组链交法,真止磁盘保存空间的管造.[提示]:(1) 假定磁盘保存空间已被区分发展度为n的等少块,公有M块可供使用.UNIX系统中采与空忙块成组链交的要领去管造磁盘保存空间,将磁盘中的每N个空忙块(N<M)分成一组,末尾一组不妨缺累N块,每组的第一齐中备案了下一组空忙块的块数战块号,第一组的块数战块号备案正在博用块中,备案的要领如下:当第一项真质为“0”时,则第二项起指出的空忙块是末尾一组.(2) 现模拟UNIX系统的空忙块成组链交,假定公有8块可供使用,每3块为一组,则空忙块成组链交的初初状态为:开初时,空忙块号是程序排列的,但是经若搞次的调配战送还支配后,空忙块的链交便一定逆次排列了.用二维数组A:array [0…M-1] of array [0…n-1]去模拟管造磁盘空间,用A[i]表示第I块,第0块A[0]动做博用块.(3) 成组链交的分组情况记录正在磁盘物理块中,为了查找链交情况,必须把它们读进主存,故当磁盘初初化后,系统先将博用块真质复造到主存中.定义一个数组MA存搁博用块真质,即MA: =A[0].申请一齐磁盘空间时,查MA,从中找出空忙块号,当一组的空忙块只剩第一齐时,则应把该块中指出的下一组的空忙块数战块号复造到博用块中,而后把该块调配给申请者.当一组的空忙块调配完后则把博用块真质(下一组链交情况)复造到主存,再为申请者调配.调配算法如图6-1.图6-1 采与成组链交的调配算法(4) 送还一齐时给出送还的块号,叵目前组不谦确定块数时,将送还块备案进该组;若目前组已谦,则另建一新组,那时送还块动做新一组的第一齐,应把主存中备案的一组链交情况MA复造到送还块中,而后正在MA沉新备案一个新组.送还一齐的算法如图6-2.图6-2 采与成组链交的回支算法(5) 安排调配战送还磁盘空间的步调,能隐现或者挨印调配的磁盘空间的块号,正在完毕一次调配或者送还后能隐现或者挨印各空忙块组的情况(各组的空忙块数战块号).原真习省去了块号与物理天点之间的变换处事,而正在本质的系统中必须举止块号与物理天点的变换处事.(6) 运止您所安排的步调,假定空忙块链交的初初状态如提示(2),现先调配4块,再依次送还第2块战第6块.把真止后调配到的块号依次隐现或者挨印出去,且隐现或者挨印空忙块组的情况.正在上次真止的前提上继承调配3块,而后送还第1块,再申请5块,隐现或者挨印依次调配到的块号及空忙块组情况.四、相闭数据结构及证明struct freeblock {int FBbegin;//起初空忙块号int num;//空忙块数char state;//状态struct freeblock *next; }struct filetowrite {char name[10];//文献名int size;//文献大小int addr_cylinder;//拆进磁盘的尾天点_柱里号int addr_track;//拆进磁盘的尾天点_磁讲号int addr_note;//拆进磁盘的尾天点_物理记录号struct filetowrite *next; }六、源代码及注释1、题一源代码:#include<stdlib.h>#include<stdio.h>int getmalloc()//调配磁盘空间 {int flag=0;struct freeblock *p=FBhead;struct filetowrite *File;File=(struct filetowrite *)malloc(sizeof(struct filetowrite));printf("输进要拆进的文献名:");scanf("%s",File->name);printf("输进所需的磁盘空间大小:");scanf("%d",&File->size);for(p=FBhead->next;p!=NULL;p=p->next)if((File->size)<=(p->num))//调配空间{flag=1;File->addr_cylinder=((p->FBbegin)/6)/20;File->addr_track=((p->FBbegin)/6)%20;File->addr_note=(p->FBbegin)%6;File->next=Filehead->next;//加进文献链表Filehead->next=File;if((File->size)<(p->num))//建改该快的起初天点战块数{p->FBbegin=p->FBbegin+File->size;p->num=p->num-File->size; }else p->state='U';break; }if(flag==0)printf("抱愧!暂时不脚够的磁盘空间调配给该文献.\n");else {printf("调配磁盘乐成!\n该文献的物理天点:\n柱里号\t 磁讲号\t物理块号\n ");printf(" %d\t %d\t %d\n",File->addr_cylinder,File->addr_tr ack,File->addr_note); } }int deletelfree()//回支磁盘空间 {char name[10]; int flag=0;struct filetowrite *p;printf("输进要简略的文献名:");scanf("%s",&name);for(p=Filehead;p->next!=NULL;p=p->next){if(strcmp(p->next->name,name)==0)//找到该文献{flag=1;int funion=0,nunion=0;int m=p->next->addr_cylinder;int n=p->next->addr_track;int k=p->next->addr_note;int addr=(m*20+n)*6+k;//起初空忙块号int tail=p->next->size+addr;struct freeblock *pnode,*qnode,*tnode,*snode;pnode=FBhead->next;while(pnode!=NULL)//先思量战后里的部分或者许有合并的情况{if((pnode->FBbegin)==tail){pnode->FBbegin=addr;pnode->num=pnode->num+p->next->size;nunion=1;break; }pnode=pnode->next; }qnode=FBhead->next;while(qnode!=NULL)//再思量是可战前里的不妨合并{if((qnode->FBbegin+qnode->num)==addr){if(nunion==0){qnode->num=qnode->num+p->next->size;funion=1;break; }else{qnode->num=qnode->num+pnode->num; tnode=FBhead;while(tnode->next!=pnode)tnode=tnode->next;tnode->next=pnode->next;free(pnode);funion=1;break;}}qnode=qnode->next; }if(funion==0&&nunion==0)//若不战前里的或者后里的举止合并,则新建一个表目{snode=(struct freeblock *)malloc(sizeof(struct freeblock));snode->FBbegin=addr;snode->num=p->next->size;snode->state='F';if(FBhead->next==NULL){FBhead->next=snode;snode->next=NULL;}else{snode->next=FBhead->next;FBhead->next=snode; } }struct filetowrite *q;q=p->next;//除该文献p->next=p->next->next;free(q); break; } }if(flag==0)printf("不该文献!\n");else {printf("文献简略乐成!\n"); }int dispfree()//隐现磁盘空忙区表{int i=1;struct freeblock *p=FBhead;printf("\n磁盘空忙区表\n");printf("序号\t起初空忙块号\t空忙块个数\t 状态\n");for(p=FBhead->next;p!=NULL;p=p->next){if((p->state)=='F')printf(" %d\t %d\t\t %d\t\t已调配\n",i++,p->FBbegin,p->num);elseprintf(" %d\t\t\t\t\t空表目\n",i++); } }int dispfile(){char name[10];struct filetowrite *p=Filehead; printf("输进要查看的文献名:");scanf("%s",&name);for(p=Filehead->next;p!=NULL;p=p->next){if(strcmp(p->name,name)==0) {printf("该文献的物理天点:\n柱里号\t磁讲号\t物理块号\n ");printf(" %d\t %d\t %d\n",p->addr_cylinder,p->addr_track, p->addr_note); break; } }if(p==NULL)printf("不该文献!\n"); }int main() {int n,i,A[MAX],B[MAX];//A[MAX]表示起初空忙块号,B[MAX]表示空忙块个数char ch;struct freeblock *pnew;FBhead=(struct freeblock *)malloc(sizeof(struct freeblock));FBhead->next=NULL;printf("输进磁盘空忙区个数:");scanf("%d",&n);for(i=1;i<=n;i++) {pnew=(struct freeblock *)malloc(sizeof(struct freeblock ));pnew->next=NULL;pnew->next=FBhead->next;FBhead->next=pnew;printf("起初空忙块号:");scanf("%d",&pnew->FBbegin);printf("空忙块个数:");scanf("%d",&pnew->num); pnew->state='F'; pnew =pnew->next; }Filehead=(struct filetowrite *)malloc(sizeof(struct filetowrite ));Filehead->next=NULL;do {system("cls");printf("\n\t\t ********** 主菜单 **********\n\n");printf("\t\t\t1.新建文献\n");printf("\t\t\t2.简略文献\n");printf("\t\t\t3.查看磁盘\n");printf("\t\t\t4.查看文献\n");printf("\t\t\t5.退出\n"); printf("请采用:");scanf("%c",&ch);switch(ch) {case '1':getmalloc();system("pause");break;case '2':deletelfree();system("pause");break;case '3':dispfree();system("pause");break;case '4':dispfile();system("pause");break;case '5':exit(1);break;default:printf("输进过得!请沉新输进.\n"); }printf("\n");getchar(); }while(ch!=4);return 0;2、题二源代码:#include <stdio.h>#include <process.h>void Initbitmap(int map[8][8]) {int cylinder,track,sector;char choice='Y';printf("初初化位视图...\n");while(choice=='y'||choice=='Y') {printf("柱里号:");scanf("%d",&cylinder);printf("磁讲号:");scanf("%d",&track);printf("物理记录号:");scanf("%d",§or);map[cylinder][4*track+sector]=1;printf("contiune?");getchar();scanf("%c",&choice); } }void allocate(int map[8][8]) {int i,j;int flag=0;int cylinder,track,sector;for(i=0;i<8;i++){ for(j=0;j<8;j++)if(map[i][j]==0){map[i][j]=1;flag=1;break;}if(flag==1) break;}if(flag==1){cylinder=i; track=j/4; sector=j%4;printf("调配到的柱里号、磁讲号、物理记录数");printf("%d\t%d\t%d",cylinder,track,sector);printf("\n"); }else printf("空间缺累,调配波折!"); }void reclaim(int map[8][8]){ int cylinder,track,sector;printf("柱里号:");scanf("%d",&cylinder);printf("磁讲号:");scanf("%d",&track);printf("物理记录号:");scanf("%d",§or);if(map[cylinder][4*track+sector]==0) {printf("此块为已调配块!回支堕落!");getchar(); }else {map[cylinder][4*track+sector]=0;printf("回支块对付应的字节号:%4d\t位数:%4d\n",cylinder,4*track+sector); } }void main() {int bitmap[8][8]; int i,j; int choice;or(i=0;i<8;i++) for(j=0;j<8;j++)bitmap[i][j]=0; Initbitmap(bitmap);while(1) {printf("\n请输进采用:");printf("1--调配,2---回支,3--隐现位示图,0--退出\n");scanf("%d",&choice); switch(choice) {case 1:allocate(bitmap);break;case 2:reclaim(bitmap);break;case 3:for(i=0;i<8;i++){for(j=0;j<8;j++)printf("%8d",bitmap[i][j]);printf("\n"); }break;case 0:exit(0);default:printf("过得采用!");break; } } }3、第三题源步调:#include<stdio.h>int MA[4]; /*空忙块数组*/intA[9][4]={{3,1,2,3},{3,4,5,6},{0,0,0,0},{0,0,0,0},{3,0,7,8}, {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; /*磁盘空间*/ int mark[9]; /*存搁已调配的块*/int No=0; /*已调配的块数*/void display1(){ int i,j,temp,count, No=0;if(MA[1]!=0){ i=MA[0];printf("\ngroup1:");for(j=1;j<=i;j++){ printf("%d ",MA[j]);mark[++No]=MA[j]; }temp=MA[1];count=2;while(A[temp][1]!=0){ printf("\ngroup%d:",count);i=A[temp][0];for(j=1;j<=i;j++){ printf("%d ",A[temp][j]);mark[++No]=A[temp][j]; }count++;temp=A[temp][1]; }printf("\ngroup%d:",count);i=A[temp][0];for(j=2;j<=i+1;j++)if(A[temp][j]>0){ printf("%d ",A[temp][j]);mark[++No]=A[temp][j]; } } else{ i=MA[0];if(i==1)printf("\nThe blocks are all assigned");else{ printf("\ngroup1:");for(j=2;j<=i;j++){ printf("%d ",MA[j]);mark[++No]=MA[j];} } } }void display() /*隐现分组情况*/{ int i,j;if(MA[0]!=0)display1();else{ i=MA[1];for(j=0;j<=3;j++)MA[j]=A[i][j];display1(); } }void assign() /*调配空忙块*/{ int s,i;if(MA[0]>1) /*若该组不只一个空忙块*/{ i=MA[0];s=MA[i];MA[0]--;printf("\nnumber of the block:%d",s); }else if(MA[0]==1) /*只剩一个空忙块*/{ if(MA[1]!=0) /*另有其余空忙块组*/ { s=MA[1];for(i=0;i<=3;i++)A[0][i]=A[s][i];MA[0]--;printf("\nnumber of the block:%d",s); }else /*不其余空忙块组*/{ printf("\nThere isn't any space");return; } }else /*目前组已调配完*/{ for(i=0;i<=3;i++)MA[i]=A[0][i];assign(); }display(); /*隐现分组情况*/}void callback() /*回支空忙块*/{ int i,j,temp;printf("\ninput the No. of the block you want to callback:");scanf("%d",&j);getchar(); /*得到待回支的空忙块号*/for(temp=1;temp<=No;temp++){ if(mark[temp]==j) break; } if(temp<No+1) /*若该空忙块已正在,退出*/{ printf("\nThe block is in the disk"); return; } if(MA[0]<3) /*目前组不谦3块*/{ i=MA[0]; MA[i+1]=j; MA[0]++; }else /*已有3块*/{ for(i=0;i<=3;i++) A[j][i]=MA[i]; MA[0]=1; MA[1]=j; }display(); /*隐现*/}void menu() /*功能采用函数*/{ int choice; char judge;printf("\ninput your choice:(1--assign,2--callback):");scanf("%d",&choice);getchar();if(choice==1)assign();else if(choice==2)callback();elseprintf("\ninvalid command!");printf("\ncontinue or not (y--Yes,n--Not):");scanf("%c",&judge);getchar();if(judge=='y')menu();else{ printf("\nNow the graph is:"); display();printf("\npress any key to quit"); getchar(); } }int main() { int i;for(i=0;i<=3;i++)MA[i]=A[0][i]; display(); menu(); }七、运止截止1、题一运止截止:2、题二运止截止:3、题三运止截止:。
主存储器空间分配和回收实验报告
软件学院计算机课程实验报告册课程名称计算机操作系统实验学期2011 年至2012 年第 2 学期学生所在院(系)软件学院年级11级专业班级软件工程1 班学生姓名朱水云学号**********指导教师陈自刚实验最终成绩软件学院实验室制2012 年4月0 5k 10k 14k 26k 32k128k 实验报告( 6 )实验名称:主存储器空间的分配和回收一、实验目的及要求:一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实验帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
二、实验内容与分析设计:本实验模拟在两种存储管理方式下的主存分配和回收。
第一题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。
[提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。
随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。
例如:操作系统作业1作业3空闲区作业2空闲区为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:起址长度状态第一栏14 K 12 K 未分配第二栏32 K 96 K 未分配空表目空表目其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白(无效),可用来登记新的空闲区(例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态)。
主存空间的分配与回收实验报告
实验报告课程名称:操作系统实验名称:主存空间的分配与回收学号: 110310014 学生姓名:于钊班级:信管1101班指导教师:吴联世实验日期: 2013 年12月5日主存回收算法)实现步骤实现动态分区的分配与回收,主要考虑三个问题:第一,设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计主存分配算法;第三,在设计的数据表格基础上设计主存回收算法。
设计记录主存使用情况的数据表格于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收变动。
总之,所有分区情况随时可能发生变化,格的设计必须和这个特点相适应。
由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。
由于分配时,空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。
主存分配时查找空闲区进行分配,然后填写已分配区表,主要操作在空闲区;某个作业执行完后,将该分区贬词空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。
由此可见,主存的分配与回收主要时对空闲区的操作。
这样为了便于对主存空间的分配与回收,就建立两张分区表记录主存的使用情况:“已分配区表”记录作业占用分区,“空闲区表”记录空闲区。
这两张表的实现方法一般由两种:链表形式、顺序表形式。
在本实验中,采用顺序表形式,用数组模拟。
由于顺序表的长度必须提前固定,所以无论是分配区表”还是“空闲区表”都必须事先确定长度。
它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因此在多数情况下,无论是“已分配表区”还是“空闲区表”都是空闲栏目。
已分配区表中除了分区起始地址、长度外,也至少还有一项“标志”,如果是空闲栏目,内容为“空”,如附录:源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node));end=(LinkList)malloc(sizeof(Node));first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){for(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("**********************************************************\n\n"); printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data.address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("**********************************************************\n\n"); }//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==request)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ) {if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ) {if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length < p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a){case 1: //默认首次适应算法if(First_fit(request)==OK) printf("\t****分配成功!****"); else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK) printf("\t****分配成功!****"); else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****"); else printf("\t****内存不足,分配失败!****");return OK;break;}}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0) {q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.state==0) {q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0) {q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0) {q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.state==0) {q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0) {q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连 {p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n"); printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("**********************************************************\n"); printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}} }。
用位示图管理磁盘空间的分配与回收设计报告
课程设计报告( 2009--2010年度第二学期)课程名称:操作系统实验课设题目: 用位示图管理磁盘空间的分配与回收院系:控制与计算机工程学院班级:姓名:指导教师:李为设计周数: 一周成绩:2010年7月9 日一、需求分析要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
(1)假定现有一个磁盘组,共40个柱面。
每个柱面4个磁道,每个磁道又划分成4个物理记录。
磁盘的空间使用情况用位示图表示。
位示图用若干个字构成,每一位对应一个磁盘块。
1表示占用,0表示空闲。
为了简单,假定字长为16位,其位示图如图9—1所示。
系统设一个变量S,记录磁盘的空闲块个数。
(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。
由位示图计算磁盘的相对块号的公式如下:相对块号一字号×16+位号之后再将相对块号转换成磁盘的物理地址:由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。
计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号×16+磁道号×4+物理块号再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号位号=磁道号×物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。
然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。
(5)设计一个回收算法,将上述已分配给用户的各盘块释放。
并显示系统各表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
柱面号=字节号
scanf("%c",&choice);
}
}
void allocate(int map[8][8])
{
int i,j;
int flag=0;
int cylinder,track,sector;
for(i=0;i<8;i++)
{ for(j=0;j<8;j++)
if(map[i][j]==0) {map[i][j]=1;flag=1;break;}
if(flag==1) break;
}
if(flag==1)
{
cylinder=i;
track=j/4;
sector=j%4;
printf("分配到的柱面号、磁道号、物理记录数");
printf("%d\t%d\t%d",cylinder,track,sector);
printf("\n");
}
else printf("空间不足,分配失败!");
5.实验报告的撰写认真、格式符合要求.
签名:金晶
日期:
成绩
磁道号=[ ]
物理记录号={ }
(3)归还一块磁盘空间时,由回收程序根据归还的磁盘物理地址计算出归还块在位示图中的对应位,把该位置成“0”。按照(2)中假设的盘组,归还块在位示图中的位置计算如下:
字节号=柱面号
位数=磁道号4+物理记录号
(4)设计申请一块磁盘空间和归还一块磁盘空间的程序。要求能显示或打印程序运行前和运行后的位示图;分配时把分配到的磁盘空间的物理地址显示或打印出来,归还时把归还块对应于位示图的字节号和位数显示或打印出来。
}
void reclaim(int map[8][8])
{ int cylinder,track,sector;
printf("柱面号:");
scanf("%d",&cylinder);
printf("磁道号:");
scanf("%d",&track);
printf("物理记录号:");
scanf("%d",§or);
实验过程中需要注意的问题:
1)明确要求:
(1)为了提高磁盘存储空间的利用率,可在磁盘上组织成链接文件、索引文件,这类文件可以把逻辑记录存放在不连续的存储空间。为了表示哪些磁盘空间已被占用,哪些磁盘空间是空闲的,可用位示图来指出。位示图由若干字节构成,每一位与磁盘上的一块对应,“1”状态表示相应块已占用,“0”状态表示该块为空闲。位示图的形式与实习二中的位示图一样,但要注意,对于主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。
}
}
void main()
{
int bitmap[8][8];
int i,j;
int choice;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
bitmap[i][j]=0;
Initbitmap(bitmap);
while(1)
{பைடு நூலகம்
printf("\n请输入选择:");
printf("1--分配,2---回收,3--显示位示图,0--退出\n");
二、实验设备(环境)及要求
微机、C++
三、实验题目
用位示图管理磁盘存储空间
四、程序中使用的数据结构及符号说明
程序中定义了3个函数:
allocate(),参数为8*8二维数组,显示位示图
reclaim(),参数为8*8回收空间
Initbitmap(),参数为8*8分配存储空间
五、源程序
#include <stdio.h>
printf("\n");
}
break;
case 0:exit(0);
default:printf("错误选择!");break;
}
}
}
六、运行调试结果
初始界面:
输入柱面号,磁道号,物理记录号:
选3,显示位示图
选1,分配存储空间:
选择3,显示位示图
选2,回收空间
七、实验心得和收获
程序中只设置了三个函数,完全实现实验的要求。
(5)假定已有如表4-1的磁盘空间被占用了,现在要申请五块磁盘空间,运行分配程序,按(4)中要求显示或打印运行的结果。然后再归还如表4-2的空间,运行回收程序,按(4)中的要求显示或打印运行结果。
七、教师评语
1.按时完成实验;
2.数据结构及符号说明完整明了;
3.有源程序清单;
4.运行调试结果有代表性;
《操作系统原理》实验报告
实验序号:3实验项目名称:磁盘存储空间的分配和回收
学 号
姓 名
专业、班
实验地点
指导教师
时间
2010.11.10
一、实验目的
磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实习使学生掌握磁盘存储空间的分配和回收算法。
scanf("%d",&cylinder);
printf("磁道号:");
scanf("%d",&track);
printf("物理记录号:");
scanf("%d",§or);
map[cylinder][4*track+sector]=1;
printf("contiune?");
getchar();
#include <process.h>
void Initbitmap(int map[8][8])
{
int cylinder,track,sector;
char choice='Y';
printf("初始化位视图...\n");
while(choice=='y'||choice=='Y')
{
printf("柱面号:");
if(map[cylinder][4*track+sector]==0)
{
printf("此块为未分配块!回收出错!");
getchar();
}
else
{
map[cylinder][4*track+sector]=0;
printf("回收块对应的字节号:%4d\t位数:%4d\n",cylinder,4*track+sector);
scanf("%d",&choice);
switch(choice)
{
case 1:allocate(bitmap);break;
case 2:reclaim(bitmap);break;
case 3:for(i=0;i<8;i++)
{for(j=0;j<8;j++)
printf("%8d",bitmap[i][j]);