川师实验六 磁盘存储空间的分配与回收

合集下载

磁盘存储空间的分配和回收1doc

磁盘存储空间的分配和回收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");}}}。

动态分区-主存储器空间的分配和回收

动态分区-主存储器空间的分配和回收

实验五Linux设备管理一. 实验目的1.掌握加载移动硬盘,U盘和光盘镜像文件。

2.掌握分区的格式化,加载等基本操作二. 实验步骤1. 分区操作(1) 在虚拟机中添加一块虚拟硬盘VM->Settings,选择Hardware选项卡,单击Add…,选择添加Hard Disk,选择Createa new virtual disk,选择SCSI,指定虚拟硬盘大小(如果超过2G,则将Split disk into2 GB files选中),指定虚拟硬盘文件位置和名字。

(2) 启动虚拟机中的Linux。

(3) 按下列步骤进行分区操作:•对系统中刚创建的硬盘进行分区:fdisk /dev/sdb••创建新的分区:输入n•创建主分区:输入p•输入分区编号:输入1•直接回车,从硬盘起始柱面创建分区•直接回车,分区大小截至到最后一个柱面(cylinder)•显示当前分区表:输入p•••删除已经存在的分区:d(注意:由于前面只分了一个分区,故没有被删除分区的编号提示选择,直接删除分区。

若有多个分区,则会出现分区的编号提示选择)。

•显示当前分区表:输入p••创建大小为500MB的1号主分区:输入n,再输入p,分区号输入1,起始柱面默认,最后柱面输入+500M。

•将磁盘剩余空间创建为编号为2的扩展分区:输入n,再输入e。

分区号输入2,起始柱面和最后柱面都默认。

••创建大小为400MB的逻辑分区:输入n,再输入l,指定分区大小为400MB •再创建大小为256MB的逻辑分区:输入n,再输入l,指定分区大小为256MB••显示当前分区表:输入p••将5号分区更改为fat32类型:输入t,再输入5,再输入C••将6号分区更改为swap类型:输入t,再输入6,再输入82••显示当前分区表:输入p••将当前的分区设置保存,并退出fdisk:输入w••在非交互状态下显示当前分区有信息:fdisk –l /dev/sdb••将/dev/sdb1格式化成ext2格式:mkfs –t ext2 /dev/sdb1••将/dev/sdb5格式化成FAT32格式:mkfs –t vfat /dev/sdb5••将/dev/sdb1加载到/mnt:mount –t ext2 /dev/sdb1 /mnt••查看/mnt中的内容:ls /mnt••卸载/dev/sdb1:umount /mnt或umount /dev/sdb1••将/dev/sdb5加载到/mnt/win:mount –t vfat /dev/sdb5 /mnt/win (若目录win不存在,则先创建)••2. 加载和卸载U盘(1) 自备一U盘,在LINUX中加载它,并列出U盘中的文件和目录。

连续磁盘存储空间的分配和回收

连续磁盘存储空间的分配和回收

/zhengjingwei1211@126/blog/static/61499280 20108217422645/磁盘存储空间的分配和回收(空闲表)#define N 5struct Empty // 空闲表结构体{int seq; //序号int start; //起始块号int count; //空闲块个数char state;//状态,F为未分配,E为空表目};struct Pan //磁盘结构体{int ZhuSeq; //柱面号int LapSeq; //磁道号int NoteSeq; //物理记录号int ZhuNum; //柱面个数int LapNum; //磁道个数int NoteNum; //物理记录个数};class CCiPan{public:Empty E[N]; //空闲表结构体数组Pan P; //磁盘public:void Display(Empty E[]); //显示空闲表void DeleteFile(Empty E[],Pan P); //删除文件,回收磁盘void CreateFile(Empty E[],Pan P); //创建文件,分配磁盘空间CCiPan();virtual ~CCiPan();};空闲表信息如下表:#include "stdafx.h"#include "CiPan.h"#include "stdio.h"#include "iostream.h"#define N 5///////////////////////////////////////////////////////////////////// /// Construction/Destruction///////////////////////////////////////////////////////////////////// /CCiPan::CCiPan(){//初始化空闲表E[0].seq=1;E[0].start=5;E[0].count=6;E[0].state='F';E[1].seq=2;E[1].start=14;E[1].count=3;E[1].state='F';E[2].seq=3;E[2].start=21;E[2].count=30;E[2].state='F';E[3].seq=4;E[3].state='E';E[4].seq=5;E[4].state='E';P.ZhuNum=200; //柱面数为200pNum=20; //磁道数为20P.NoteNum=6; //物理记录数为6}CCiPan::~CCiPan(){}void CCiPan::CreateFile(Empty E[],Pan P){int Block;Empty e;int i,j,M;cout<<"请输入所建立文件的记录块数:";cin>>Block;for(i=0;i<N;i++){if(i>=N-1 && E[i].count<Block){//当比较到最后一个未找到空闲块大小符合所要分配的文件大小时cout<<"磁盘空间不足!"<<endl;}if(E[i].count>Block){//当文件大小小于磁盘空闲块大小时,只改变空闲表中起始块号与空闲块个数M=E[i].start/P.NoteNum;P.ZhuSeq=M/P.ZhuNum; //计算柱面号pSeq=M%P.ZhuNum; //计算磁道号P.NoteSeq=E[i].start%P.NoteNum; //计算物理记录号E[i].start+=Block; //起始块号改变,增加量为文件大小E[i].count-=Block; //空闲块个数,减少量为文件大小cout<<endl;cout<<"成功为文件分配了磁盘空间!"<<endl;cout<<"为文件分配的物理地址为:"<<endl; //显示为文件分配的物理地址 cout<<"柱面号:"<<P.ZhuSeq<<endl;cout<<"磁道号:"<<pSeq<<endl;cout<<"物理记录号:"<<P.NoteSeq<<endl;break;}else{if(E[i].count==Block){ //文件大小与空闲块号个数刚好相等M=E[i].start/P.NoteNum;P.ZhuSeq=M/P.ZhuNum; //计算柱面号pSeq=M%P.ZhuNum; //计算磁道号P.NoteSeq=E[i].start%P.NoteNum; //计算物理记录号E[i].seq=N; //将刚分配出去的空间序号改为最后一项,等待将其插入到表末尾E[i].state='E'; //将状态改为“空表目”cout<<endl;cout<<"成功为文件分配了磁盘空间!"<<endl;cout<<"为文件分配的物理地址为:"<<endl;//显示为文件分配的物理地址 cout<<"柱面号:"<<P.ZhuSeq<<endl;cout<<"磁道号:"<<pSeq<<endl;cout<<"物理记录号:"<<P.NoteSeq<<endl;e=E[i]; //记录下刚分配出去的空闲块j=i;for(i=j;i<N;i++){//将状态为“空表目”的一项插入到表末尾E[i]=E[i+1];--E[i].seq; //向前移一项,序号减1E[N-1]=e;}break;}}}}void CCiPan::DeleteFile(Empty E[],Pan P){int i,j,m,k,n;Empty e,y;cout<<"请输入柱面号:";cin>>P.ZhuSeq;cout<<"请输入磁道号:";cin>>pSeq;cout<<"请输入物理记录号:";cin>>P.NoteSeq;cout<<"请输入块号:";cin>>m;for(i=0;i<N;i++){if(E[i].state=='E'){E[i].start=(P.ZhuSeq*pNum+pSeq)*P.NoteNum+P.NoteSeq; //计算起始块号E[i].count=m; //计算空闲块个数E[i].state='F';//回收后将状态改为“未分配”y=E[i];for(j=0;j<i;j++){if(E[j].start+E[j].count==E[i].start)//上临{if(E[i].start+E[i].count==E[j+1].start) //既上临又下临{E[j].count=E[i].count+E[j].count+E[j+1].count;E[j+1].count=' ';E[j+1].start=' ';E[j+1].state='E';E[j+1].seq=N;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"既上临又下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j].start<<"空闲块个数为:"<<E[j].count<<endl;e=E[j+1];k=j+1;for(n=k;n<N;n++){//将状态为“空表目”的一项插入到表末尾E[n]=E[n+1];--E[n].seq; //向前移一项,序号减1E[N-1]=e;}}else//只上临{E[j].count+=E[i].count;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"只上临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j].start<<"空闲块个数为:"<<E[j].count<<endl;}}else{if(E[i].start+E[i].count==E[j+1].start) //只下临{E[j+1].count+=E[i].count;E[j+1].start=E[i].start;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"只下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j+1].start<<"空闲块个数为:"<<E[j+1].count<<endl;}else//都不临{if(E[i].start>E[j].start && E[i].start<E[j+1].start){cout<<"既不上临又不下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[i].start<<"空闲块个数为:"<<E[i].count<<endl;for(int t=i;t>j+1;t--) //{E[t]=E[t-1];E[t].seq++;}E[j+1]=y;}else{if(E[i].start==E[j+1].start){E[j+1].start=E[i].start;E[j+1].count=E[i].count;E[j+1].state=E[i].state;cout<<"既不上临又不下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[i].start<<"空闲块个数为:"<<E[i].count<<endl;}}}}}break;}}}void CCiPan::Display(Empty E[]){int i;cout<<"序号\t"<<"起始空闲块号\t"<<"空闲块个数\t"<<"状态"<<endl;for(i=0;i<N;i++){if(E[i].state=='F') //显示空闲表cout<<E[i].seq<<"\t"<<E[i].start<<"\t\t"<<E[i].count<<"\t\t"<<E[i] .state<<endl;elsecout<<E[i].seq<<"\t\t\t\t\t"<<E[i].state<<endl;}}/zx0071/blog/item/2490652da25cdeeb8a1399b4.html。

内存的分配和回收分区链实验报告按照这个内容来完成

内存的分配和回收分区链实验报告按照这个内容来完成

一、实验目的理解分区式存储管理的基本原理,熟悉分区分配和回收算法。

即理解在不同的存储管理方式下,如何实现主存空间的分配与回收;并掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、设备与环境1. 硬件设备:PC机一台2. 软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如VC \VC++\Java 等编程语言环境。

三、实验原理实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

A、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

B、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。

存储器的分配与回收算法实现

存储器的分配与回收算法实现

实验内容:模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。

采用最先适应法、最佳适应法、最坏适应法分配主存空间。

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

若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。

当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。

运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。

实验要求:详细描述实验设计思想、程序结构及各模块设计思路;详细描述程序所用数据结构及算法;明确给出测试用例和实验结果;为增加程序可读性,在程序中进行适当注释说明;认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;实验报告撰写要求结构清晰、描述准确逻辑性强;【实验过程记录(源程序、测试用例、测试结果及心得体会等)】#include<stdio.h>#include<malloc.h>#define NULL 0#define LEN1 sizeof(struct job)//作业大小#define LEN2 sizeof(struct idle)//空闲区单元大小#define LEN3 sizeof(struct allocate)//已分配区单元大小int SPACE=100;//定义内存空间大小int ORIGI=1;//定义内存起始地址struct job//定义作业{int name;int size;int address;};struct idle//定义空闲区{int size;int address;struct idle *next;};struct allocate//定义已分配区{int name;int size;int address;struct allocate *next;};struct idle *creatidle(void)//建立空闲表{struct idle *head;struct idle *p1;p1=(struct idle*)malloc(LEN2);p1->size=SPACE;p1->address=ORIGI;p1->next=NULL;head=p1;return(head);}struct allocate *creatallocate(void)//建立已分配表{struct allocate *head;head=NULL;return(head);}struct job *creatjob(void)//建立作业{struct job *p;p=(struct job*)malloc(LEN1);printf("请输入要运行的作业的名称与大小:\n");scanf("%d%d",&p->name,&p->size);return(p);}struct idle *init1(struct idle *head,struct job *p)//首次适应算法分配内存{struct idle *p0,*p1;struct job *a;a=p;p0=head;p1=p0;while(p0->next!=NULL&&p0->size<a->size){p0=p0->next;}if(p0->size>a->size){p0->size=p0->size-a->size;a->address=p0->address;p0->address=p0->address+a->size;}else{printf("无法分配\n");}return(head);}struct idle *init2(struct idle *head,struct job *p)//最优{struct idle *p0,*p1;struct job *a;a=p;p0=head;if(p0==NULL){printf("无法进行分配!\n");}while(p0->next!=NULL&&p0->size<a->size){p0=p0->next;}if(p0->size>a->size){p1=p0;p0=p0->next;}else{printf("无法分配!\n");}while(p0!=NULL){if(p0->size>p1->size){p0=p0->next;}else if((p0->size<p1->size)&&(p0->size>a->size)){p1=p0;p0=p0->next;}}p1->size=(p1->size)-(a->size);a->address=p1->address;p1->address=(p1->address)+(a->size);return(head);}struct idle *init3(struct idle *head,struct job *p)//最差{struct idle *p0,*p1;struct job *a;a=p;p0=head;if(p0==NULL){printf("无法进行分配!");}while(p0->next!=NULL&&p0->size<a->size){p0=p0->next;}if(p0->size>a->size){p1=p0;p0=p0->next;}else{printf("无法分配!\n");}while(p0!=NULL){if(p0->size<p1->size){p0=p0->next;}else if(p0->size>p1->size){p1=p0;p0=p0->next;}}p1->size=(p1->size)-(a->size);a->address=p1->address;p1->address=(p1->address)+(a->size);return(head);}struct allocate *reallocate(struct allocate *head,struct job *p)//重置已分配表{struct allocate *p0,*p1,*p2;//*p3,*p4;struct job *a;//struct idle *b;a=p;p0=(struct allocate*)malloc(LEN3);p1=(struct allocate*)malloc(LEN3);if(head==NULL){p0->name=a->name;p0->size=a->size;p0->address=ORIGI;p0->next=NULL;head=p0;}Else{p1->name=a->name;p1->size=a->size;p1->address=a->address;p2=head;while(p2->next!=NULL){p2=p2->next;} p2->next=p1;p1->next=NULL;}return(head);}struct allocate *del(struct allocate *head,struct job *p)//删除指定的作业{struct job *p1;struct allocate *p2,*p3;p2=head;p1=p;while((p1->name!=p2->name)&&(p2->next!=NULL)){p3=p2;p2=p2->next;}if(p1->name==p2->name){if(p2==head)head=p2->next;elsep3->next=p2->next;}return(head);}struct job *delejob(struct allocate *head){struct job *p1;struct allocate *p2;int num;p1=(struct job*)malloc(LEN1);printf("请输入要删除的作业的名称\n");scanf("%d",&num);p2=head;while((num!=p2->name)&&(p2->next!=NULL)){p2=p2->next;}if(num==p2->name){p1->name=p2->name;p1->size=p2->size;p1->address=p2->address;}return(p1);}struct idle *unite(struct job *p,struct idle *head)//合并相邻内存空间{struct idle *p1,*p2,*p3;struct job *m;m=p;p1=head;p3=(struct idle*)malloc(LEN2);while((p1->address<m->address)&&(p1->next!=NULL)){p2=p1;p1=p1->next;}if(m->address<p1->address){if(head==p1){p3->size=m->size;p3->address=m->address;if((p1->address-p3->address)==(p3->size)){p1->address=p3->address;p1->size=p3->size+p1->size;}else{head=p3;p3->next=p1;}}else{p3->size=m->size;p3->address=m->address;if((p1->address-p3->address)==(p3->size)){p1->address=p3->address;p1->size=p3->size+p1->size;if((p3->address-p2->address)==(p2->size)){p2->size=p1->size+p2->size;p2->next=p1->next;}else{p2->next=p1;}}else{if((p3->address-p2->address)==(p2->size)){p2->size=p2->size+p3->size;}else{p3->next=p1;p2->next=p3;}}}}else{p3->size=m->size;p3->address=m->address;if((p3->address-p1->address)==(p1->size)){p1->size=p1->size+p3->size;}else{p1->next=p3;p3->next=NULL;}}return(head);}void print(struct idle *h1,struct allocate *h2){struct idle *m1;struct allocate *n1;m1=h1;n1=h2;if(m1==NULL){printf("空闲表为空!\n");}else{while(m1!=NULL){printf("空闲单元地址为%d,其大小为%d\n",m1->address,m1->size);m1=m1->next;}}if(n1==NULL){printf("已分配表为空!\n");}else{while(n1!=NULL){printf("已分配单元地址为%d,其大小为%d,其名称为%d\n",n1->address,n1->size,n1->name);n1=n1->next;}}}void FF(void){struct idle *p1;struct allocate *p2;struct job *p,*q;int y=1;int n=0;int a=1;int c;p1=creatidle();p2=creatallocate();printf("初始情况为:\n");print(p1,p2);while(a==y){printf("请输入要进行的操作:1.建立作业 2.删除作业 3.结束操作\n");scanf("%d",&c);switch(c){case 1:p=creatjob();p1=init1(p1,p);p2=reallocate(p2,p);print(p1,p2);break;case 2:q=delejob(p2);p2=del(p2,q);//p2=reallocate(p2,q);p1=unite(q,p1);print(p1,p2);break;case 3:y=0;break;}}}void BF(void){struct idle *p1;struct allocate *p2;struct job *p,*q;int y=1;int n=0;int a=1;int c;p1=creatidle();p2=creatallocate();printf("初始情况为:\n");print(p1,p2);while(a==y){printf("请输入要进行的操作:1.建立作业 2.删除作业 3.结束操作\n");scanf("%d",&c);switch(c){case 1:p=creatjob();p1=init2(p1,p);p2=reallocate(p2,p);print(p1,p2);break;case 2:q=delejob(p2);p2=del(p2,q);//p2=reallocate(p2,q);p1=unite(q,p1);print(p1,p2);break;case 3:y=0;break;}}}void WF(void){struct idle *p1;struct allocate *p2;struct job *p,*q;int y=1;int n=0;int a=1;int c;p1=creatidle();p2=creatallocate();printf("初始情况为:\n");print(p1,p2);while(a==y){printf("请输入要进行的操作:1.建立作业 2.删除作业 3.结束操作\n");scanf("%d",&c);switch(c){case 1:p=creatjob();p1=init3(p1,p);p2=reallocate(p2,p);print(p1,p2);break;case 2:q=delejob(p2);p2=del(p2,q);//p2=reallocate(p2,q);p1=unite(q,p1);print(p1,p2);break;case 3:y=0;break;}}}运行结果如下1.首次适应算法建立作业2.最优适应算法建立作业3.最差适应算法建立并删除作业。

存储器的分配与回收算法实现

存储器的分配与回收算法实现

存储器的分配与回收算法实现一、引言存储器的分配与回收算法是计算机操作系统中的重要内容之一。

它涉及到内存管理、进程管理等多个方面,对计算机系统的性能和稳定性都有着重要的影响。

本文将从存储器分配与回收算法的基本原理、常见算法及其实现方式等方面进行详细介绍。

二、存储器分配与回收算法基本原理1. 存储器分配在计算机系统中,进程需要使用一定数量的内存空间来运行。

因此,操作系统需要为每个进程分配一定数量的内存空间。

存储器分配就是指操作系统为进程分配内存空间的过程。

2. 存储器回收当一个进程不再需要使用某段内存空间时,操作系统需要将该段内存空间释放出来,以便其他进程使用。

这个过程称为存储器回收。

三、常见的存储器分配与回收算法1. 首次适应算法(First Fit)首次适应算法是最简单、最常用的一种内存分配方法。

该方法从低地址开始查找可用块,并选择第一个满足要求(大小大于或等于所需大小)的块进行分配。

优点:实现简单,效率高。

缺点:容易产生内存碎片,导致内存利用率低。

2. 最佳适应算法(Best Fit)最佳适应算法是一种比首次适应算法更为优化的算法。

该算法从所有可用块中选择最小的一个块进行分配。

优点:可以有效减少内存碎片,提高内存利用率。

缺点:实现复杂度高,效率较低。

3. 最差适应算法(Worst Fit)最差适应算法是一种与最佳适应算法相反的方法。

该方法选择可用块中最大的一个块进行分配。

优点:容易实现,效率较高。

缺点:会产生大量的内存碎片,降低了内存利用率。

4. 快速适应算法(Quick Fit)快速适应算法是一种基于链表结构的动态分配方法。

该方法将可用块按照大小分类,并将它们组织成多个链表。

当需要分配内存时,只需在对应大小的链表中查找可用块即可。

优点:能够快速地找到合适大小的空闲块,提高了效率和内存利用率。

缺点:实现复杂度较高,需要维护多个链表结构。

四、常见的存储器分配与回收算法实现方式1. 静态分配静态分配是指在程序运行之前就确定好内存的使用情况,将内存空间划分为不同的区域,并为每个区域分配固定大小的内存空间。

内存分配回收实验报告

内存分配回收实验报告

一、实验目的通过本次实验,加深对内存分配与回收机制的理解,掌握内存分配算法和回收策略,并能够运用所学知识解决实际内存管理问题。

二、实验内容1. 确定内存空间分配表;2. 采用首次适应算法实现内存分配;3. 采用最佳适应算法实现内存分配;4. 采用最坏适应算法实现内存分配;5. 实现内存回收功能;6. 对比分析不同内存分配算法的优缺点。

三、实验步骤1. 创建一个内存空间模拟程序,用于演示内存分配与回收过程;2. 定义内存空间分配表,记录内存块的起始地址、大小和状态(空闲或占用);3. 实现首次适应算法,在内存空间分配表中查找第一个满足条件的空闲内存块,分配给请求者;4. 实现最佳适应算法,在内存空间分配表中查找最接近请求大小的空闲内存块,分配给请求者;5. 实现最坏适应算法,在内存空间分配表中查找最大的空闲内存块,分配给请求者;6. 实现内存回收功能,当内存块释放时,将其状态更新为空闲,并合并相邻的空闲内存块;7. 对比分析不同内存分配算法的优缺点,包括分配时间、内存碎片和内存利用率等方面。

四、实验结果与分析1. 首次适应算法:该算法按照内存空间分配表的顺序查找空闲内存块,优点是分配速度快,缺点是容易产生内存碎片,且内存利用率较低;2. 最佳适应算法:该算法查找最接近请求大小的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多;3. 最坏适应算法:该算法查找最大的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多。

五、实验结论通过本次实验,我们掌握了内存分配与回收的基本原理和算法,了解了不同内存分配算法的优缺点。

在实际应用中,我们需要根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。

六、实验心得1. 内存分配与回收是计算机系统中重要的组成部分,对系统性能有着重要影响;2. 熟练掌握内存分配算法和回收策略,有助于解决实际内存管理问题;3. 在实际应用中,应根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。

存储器的分配与回收算法实现

存储器的分配与回收算法实现

存储器的分配与回收算法实现1. 引言在计算机系统中,存储器(Memory)是一种用于存储和检索数据的重要资源。

存储器的分配与回收算法实现是操作系统中的一项关键任务,它负责管理和组织存储器的分配与释放。

本文将深入探讨存储器的分配与回收算法实现的原理、常用算法及其优化方法。

2. 存储器的组织与分配2.1 存储器的组织存储器可以分为物理存储器和逻辑存储器。

物理存储器是计算机硬件中的实际存储器,如RAM(Random Access Memory)和ROM(Read-Only Memory);而逻辑存储器是在操作系统中抽象出来的概念,用于完成存储器的管理。

逻辑存储器可以通过分区、分页和段落等方式进行组织。

其中,分区是将物理存储器划分为若干个连续的大小相等或不等的区域,用于存放进程或数据;分页则将物理存储器划分为固定大小的页框,并将逻辑存储器划分为相同大小的页;段落则将物理存储器划分为不同大小的段,每个段可包含若干页。

2.2 存储器的分配方式存储器的分配方式通常包括固定分区分配和动态分区分配。

固定分区分配将物理存储器分为若干个固定大小的分区,每个分区可分配给一个进程或数据。

固定分区分配的特点是简单、高效,但会造成存储器的内部碎片。

动态分区分配则按需为进程或数据分配存储区域,可以更加灵活地利用存储器资源。

动态分区分配的主要算法包括首次适应算法、最佳适应算法和最坏适应算法等。

3. 存储器的回收算法存储器的回收算法是将不再使用的存储区域回收,并将其释放给其他进程使用的过程。

常用的存储器回收算法包括垃圾回收算法和页面置换算法。

3.1 垃圾回收算法垃圾回收算法是在动态内存分配中常用的一种回收算法,它通过自动检测和回收不再使用的存储空间,以避免内存泄漏和内存溢出等问题。

常见的垃圾回收算法包括引用计数法、标记-清除法和复制算法等。

•引用计数法:该算法通过记录每个对象被引用的次数来进行垃圾回收。

当一个对象被引用时,其引用计数加1;当一个对象不再被引用时,其引用计数减1。

内存的分配与回收实验报告(最先适应法)

内存的分配与回收实验报告(最先适应法)

代码实现如下:#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,直到完成所有的进程请求。

实验结果:经过多次实验,使用最先适应算法进行内存分配与回收,可以有效地利用内存空间,提高内存利用率。

实验总结:通过本次实验,我深入理解了最先适应算法的实现原理和逻辑流程。

在实际的内存管理中,我们需要根据实际情况选择合适的内存分配策略,以避免出现内存碎片和浪费现象。

同时,回收后的内存块需要及时进行合并操作,以提高内存的利用率。

实验过程中还发现,在有大量并发的情况下,最先适应算法可能会产生较多的内存碎片,影响内存的使用效率,因此需要根据实际情况选择其他适合的内存分配算法。

总之,通过这次实验,我对内存分配与回收有了更深入的理解,对内存管理算法的选择和优化也更加清晰,为以后的实际应用打下了基础。

简述内存空间的分配和回收的含义与处理方法。

简述内存空间的分配和回收的含义与处理方法。

内存空间的分配和回收是操作系统存储管理的重要功能。

内存空间的分配是指将内存空间分配给进程或程序的过程。

在分配内存空间时,操作系统需要确定申请者的需求,并根据一定的策略和规则找出足够的空间进行分配。

这些策略和规则可以包括按需分配、最先适应、最佳适应和最坏适应等。

内存空间的回收则是指当进程或程序结束运行时,操作系统需要将其所占用的内存空间收回,以便重新分配给其他进程或程序使用。

回收内存空间时,操作系统需要进行一系列操作,例如将回收的内存空间标记为空闲区域,以便后续的分配使用。

对于内存空间的分配和回收,操作系统通常会设置一张表格来记录内存的使用情况,包括哪些区域尚未分配,哪些区域已经分配以及分配给哪些进程等。

这样,系统可以根据申请者的要求和表格记录的信息,快速有效地进行内存空间的分配和回收。

以上信息仅供参考,如有需要,建议查阅相关书籍或咨询专业人士。

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告(DOC)

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告(DOC)

计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号: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)在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收二、实验目的:通过本实习帮助理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。

三、实验原理:第一题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收(1)可变分区方式是按作业需要的主存空间大小来分割分区的。

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

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

例如:为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:(2)当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

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

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

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

为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。

(3)采用最先适应算法(顺序分配算法)分配主存空间。

按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。

当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。

最先适应分配算法如图:(4)当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。

例如,在提示(1)中列举的情况下,如果作业2撤离,归还所占主存区域时,应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。

磁盘存储空间的分配和回收

磁盘存储空间的分配和回收

真习六磁盘保存空间的调配战回支之阳早格格创做一、真习真质模拟磁盘空忙空间的表示要领,以及模拟真止磁盘空间的调配战回支.二、真习手段磁盘初初化时把磁盘保存空间分成许多块(扇区),那些空间不妨被多个用户共享.用户做业正在真止功夫时常要正在磁盘上建坐文献或者把已经建坐正在磁盘上的文献删去,那便波及到磁盘保存空间的调配战回支.一个文献存搁到磁盘上,不妨构造成程序文献(连绝文献)、链交文献(串联文献)、索引文献等,果此,磁盘保存空间的调配有二种办法,一种是调配连绝的保存空间,另一种是不妨调配不连绝的保存空间.何如灵验天管造磁盘保存空间是支配系统应办理的一个要害问题,通过原真习使教死掌握磁盘保存空间的调配战回支算法.三、真习题目原真习模拟三种磁盘保存空间的管造要领.第一题:连绝的磁盘保存空间的调配战回支.[提示]:(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",&sector);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",&sector);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、题三运止截止:。

操作系统-内存分配与回收模拟-实验06

操作系统-内存分配与回收模拟-实验06

操作系统课程实验报告
(1)首次适应算法实现
从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。

为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。

该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

(2)最佳适应算法实现
它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。

为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。

数据结构体分析
(3)内存回收
将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。

并判断该空闲块是否与其他空闲块相连,若释放的内存空间与空闲块相连时,则合并为同一个空闲块,同时修改分区大小及起始地址。

首次适配算法流程图:
最佳适配算法流程图:
内存回收:
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#define M 20
#define N 101
#define max_size 128
int i = 0,choose;
int id= 0,size = 0,countOfEmpty = 1,countOfNotEmpty = 0,num = 1;。

主存储器空间的分配和回收实验报告

主存储器空间的分配和回收实验报告

主存储器空间的分配和回收实验报告主存储器是计算机中一种重要的存储设备,它用于存储程序的指令和数据。

在计算机系统中,主存储器的空间分配和回收是一个关键的问题。

为了研究主存储器空间的分配和回收,我们进行了一系列实验。

实验目的:1.了解主存储器的空间分配和回收原理;2.掌握主存储器空间分配和回收的算法和方法;3.借助实验了解主存储器空间分配和回收对系统性能的影响。

实验步骤:1.设计一个模拟的主存储器,包括地址空间和物理存储空间。

我们将地址空间划分为多个固定大小的块,每个块对应一个页面。

2.实现主存储器的空间分配算法。

我们选择了最先适应算法,即从低地址开始寻找第一个可以容纳所需页面的空闲块。

3.实现主存储器的空间回收算法。

我们选择了简单的空闲块链表算法,即将回收的空间加入到一个空闲块链表中。

4.编写测试程序,模拟实际系统中的内存分配和回收操作。

测试程序包括创建新进程,分配内存空间,释放内存空间等操作。

5.对测试程序进行性能评测,比较不同算法和策略下的主存储器使用效率和系统性能。

实验结果:通过对实验数据的分析和对比,我们得出了以下结论:1.最先适应算法在空间分配方面具有较好的效果,能够快速找到合适的空闲块。

2.简单的空闲块链表算法能够有效地回收空间,减少内存碎片的产生。

3.不同的内存分配策略会对系统性能产生影响,合理选择内存管理算法是提高系统性能的关键。

结论:本次实验通过对主存储器空间的分配和回收进行实验研究,掌握了主存储器空间分配和回收的算法和方法,并通过实验结果对主存储器的性能进行了评估和分析。

实验结果表明最先适应算法和简单的空闲块链表算法是有效的方法,能够提高主存储器的使用效率和系统性能。

在实际系统中,我们需要根据具体情况选择合适的算法和策略,以满足系统的需求。

操作系统实验——磁盘存储空间的分配和回收C++源程序

操作系统实验——磁盘存储空间的分配和回收C++源程序

#include<stdio.h>#include<stdlib.h>#define NUM 128typedef struct{ int zm_no;int cd_no;int jl_no;}disk;void disp(int m[]){int i;printf("位?示º?图ª?:êo\n");for(i=0;i<NUM;i++){if(i%8==0)printf("\n");printf("%d\t",m[i]);}printf("\n");}void creat(int m[]){ int j=0,zh,wh;int keyong=0;while(j<NUM){ if(m[j]==0){ keyong=1;m[j]=1;disk a;a.zm_no=j/8;a.cd_no=(j%8)/4;a.jl_no=(j%8)%4;zh=a.zm_no;wh=a.cd_no*4+a.jl_no;printf("柱¨´面?号?\t磁ä?道̨¤号?\t物?理¤¨ª记?录?号?\n");printf("%d\t%d\t%d\n",a.zm_no,a.cd_no,a.jl_no);printf("字Á?号?\t位?号?\n");printf("%d\t%d\n",zh,wh);break;}else j++;}if(keyong==0){ printf("无T可¨¦用®?磁ä?盘¨¬块¨¦!ê?\n");printf("\n");}}void del(int m[]){ disk b;int zm_no,cd_no,jl_no,j;printf("输º?入¨?待äy回?收º?磁ä?盘¨¬块¨¦的Ì?柱¨´面?号?,ê?磁ä?道̨¤号?,ê?物?理¤¨ª记?录?号?:êo");scanf("%d%d%d",&b.zm_no,&b.cd_no,&b.jl_no);j=8*b.zm_no+4*b.cd_no+b.jl_no;if(m[j]==0)printf("已°?是º?空?闲D状Á¡ä态¬?,ê?不?必À?回?收º?!ê?\n");else{ m[j]=0;disp(m);}}int main(){int i;int input=1;int m[NUM]={ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};while(input!=0){ printf("1.当Ì¡À前¡ã磁ä?盘¨¬状Á¡ä态¬? 2.申¦¨º请?磁ä?盘¨¬块¨¦ 3.回?收º?磁ä?盘¨¬块¨¦ 0.退ª?出?\n");scanf("%d",&input);switch(input){ case 1: disp(m);break;case 2: creat(m);break;case 3: del(m);break;default:break;}}system("pause");return 0;}。

磁盘存储空间的分配和回收

磁盘存储空间的分配和回收

实习六磁盘存储空间的分配和回收一、实习内容模拟磁盘空闲空间的表示方法,以及模拟实现磁盘空间的分配和回收。

二、实习目的磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。

用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。

一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。

怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实习使学生掌握磁盘存储空间的分配和回收算法。

三、实习题目本实习模拟三种磁盘存储空间的管理方法。

第一题:连续的磁盘存储空间的分配和回收。

[提示]:(1) 要在磁盘上建立顺序文件时,必须把按序排列的逻辑记录依次存放在磁盘的连续存储空间中。

可假定磁盘初始化时,已把磁盘存储空间划分成若干等长的块(扇区),按柱面号和盘面号的顺序给每一块确定一个编号。

随着文件的建立、删除、磁盘存储空间被分成许多区(每一区包含若干块),有的区存放着文件,而有的区是空闲的。

当要建立顺序文件时必须找到一个合适的空闲区来存放文件记录,当一个文件被删除时,则该文件占用的区应成为空闲区。

为此可用一张空闲区表来记录磁盘存储空间中尚未占用的部分,格式如下:(2) 要建立文件时,先查找空闲区表,从状态为“未分配”的登记栏目中找出一个块数能满足要求的区,由起始空闲块号能依次推得可使用的其它块号。

若不需要占用该区的所有块时,则剩余的块仍应为未分配的空闲块,这时要修改起始空闲块号和空闲块数。

若占用了该区的所有块,则相应登记栏中的状态修改成“空表目”。

删除一个文件时,从空闲区表中找一个状态为“空表目”的登记栏目,把归还的起始块号和块数填入对应的位置。

磁盘存储空间的分配和回收算法类似于主存储器的可变分区方式的分配和回收。

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

数学与软件科学学院实验报告
学期:__2019 至_ 2020 第_ 1 学期 2019年 12 月 5日课程名称:_ 计算机操作系统专业:__ 信息与计算科学级 _ 班
实验编号: 6 实验项目:磁盘存储空间的分配与回收指导教师:
姓名:学号:实验成绩:
实验六磁盘存储空间的分配与回收
(综合性实验2学时)
1、实验目的
掌握磁盘空间的分配与回收的基本思想及实现方法。

2、实验内容
模拟采用位示图管理磁盘空间的分配与回收。

要求输出运行前后的位示图,以及分配和回收磁盘的物理地址。

3、实验准备
理解采用位示图实现磁盘空间的分配与回收的基本思想与方法。

4.实验过程
一、需求分析
要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程(1)假定现有一个磁盘组,共40个柱面。

每个柱面4个磁道,每个磁道又划分成4个物理记录。

磁盘的空间使用情况用位示图表示。

位示图用若干个字构成,每一位对应一个磁盘块。

1表示占用,0表示空闲。

为了简单,假定字长为16位,其位示图如图所
位示图
(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。

由位示图计算磁盘的相对块号的公式如下:
相对块号一字号×16+位号
之后再将相对块号转换成磁盘的物理地址:
由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号
磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商
物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数
(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。

计算公式如下:
先由磁盘地址计算相对块号:
相对块号=柱面号×16+磁道号×4+物理块号
再计算字号和位号:
字号=相对块号/16的商,也即字号=柱面号
位号=磁道号×物理块数/每磁道+物理块号
(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。

然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。

(5)设计一个回收算法,将上述已分配给用户的各盘块释放。

并显示系统各表。

回收算法框图如图5所示。

二、整体功能及设计
程序整体主要有三个功能模块,分别是:初使化、分配以及回收。

当点击相应按钮时实现其功能。

使用二维数组array1_after[50][16]、array1_before[50][16]、array2_after[50][16]分别记录分配前、分配后、回收后的位示图的使用情况,使用表格m_list1_after、m_list1_before、m_listafter显示位示图的使用情况。

程序设计了三个方法,分别是初始化OnInitDialog()、分配算法OnButtonFp()、回收算法OnButtonHs()。

磁盘空间分配框图如图所示
磁盘空间回收框图如图所示
三.结果分析
程序满足要求,测试通过
四.心得体会
掌握磁盘空间的分配与回收的基本思想及实现方法,并理解采用位示图实现磁盘空间的分配与回收的基本思想与方法。

相关文档
最新文档