3磁盘存储空间的分配和回收3.1实验内容及要求实验内容:用位示图管理磁盘存储空间。实验要求:能接受来自键盘的空间申请及释放请求,要求能显示或打印程序运行前和运行后的位示图;分配时把分配到的磁盘空间的物理地址显示或打印出来,归还时把归还块对应于位示图的字节号和位数显示或打印出来。3.2实验目的磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实验有利于掌握磁盘存储空间的分配和回收算法。3.3实验环境本实验的设计基于Windows7操作系统DevC++5.11环境,用C语言实现编程。3.4实验思路(1)为了提高磁盘存储空间的利用率,可在磁盘上组织成链接文件、索引文件,这类文件可以把逻辑记录存放在不连续的存储空间。为了表示哪些磁盘空间已被占用,哪些磁盘空间是空闲的,可用位示图来指出。位示图由若干字节构成,每一位与磁盘上的一块对应,“1”状态表示相应块已占用,“0”状态表示该块为空闲。位示图的形式与实验二中的位示图一样,但要注意,对于主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。(2)申请一块磁盘空间时,由分配程序查位示图,找出一个为“0”的位,计算出这一位对应块的磁盘物理地址,且把该位置成占用状态“1”。假设现在有一个盘组共8个柱面,每个柱面有2个磁道(盘面),每个磁道分成4个物理记录。那么,当在位示图中找到某一字节的某一位为“0”时,这个空闲块对应的磁盘物理地址为:柱面号=字节号磁道号=位数/4物理记录号=位数%4(3)归还一块磁盘空间时,由回收程序根据归还的磁盘物理地址计算出归还块在位示图中的对应位,把该位置成“0”。按照(2)中假设的盘组,归还块在位示图中的位置计算如下:字节号=柱面号位数=磁道号4+物理记录号(4)设计申请磁盘空间和归还磁盘空间的程序。3.5数据结构与全局变量位示图采用的数据结构:typedefstructbitMap{intbitMap[COUNT];charfileTag[COUNT][32];//存储在该块的文件名}BitMap;全局变量:BitMap*bitPointer;3.6函数说明(1)主函数main()调用init()进行初始化,提示用户输入操作数并调用相应的函数进行磁盘分配、回收,输出操作后位示图或退出程序操作(2)初始化函数init()初始化位示图全0,表示未被占用(3)输出函数showbitmap()和showfile()printBitMap()输出位示图占用情况,showFile()输出“磁盘”上的文件以便于用户根据文件名回收盘块。(4)磁盘分配函数diskallocate()提示用户输入分配请求,按照用户要求为文件分配磁盘空间并显示分配分配情况。(5)磁盘回收函数diskrecycle()根据用户回收请求回收相应盘块并显示回收情况。3.7运行结果依次分配10、20、40块,结果如下:依次回收a、b,结果如下:3.8实验心得主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。3.9实验代码#includestdio.h#includestdlib.h#includestring.h#defineCOUNT64#defineCYLINDER8#defineTRACK_PER_CYLINDER2#defineSECTOR_PER_TRACK4#defineSECTOR_PER_CYLINDER8typedefstructbitMap//定义位示图{intbitMap[COUNT];charfileTag[COUNT][32];//文件标志如磁盘文件名}BitMap;BitMap*bitPointer=NULL;voidinit(){bitPointer=(BitMap*)malloc(sizeof(BitMap));for(intk=0;jCOUNT;k++){bitPointer-bitMap[k]=0;memset(bitPointer-fileTag[k],0,sizeof(char)*32);}}voidprintBitMap(void){printf(当前系统磁盘位示图(0表示块可用,1表示不可用):);for(inti=0;iCOUNT;i++){if(i%8==0)printf(\n);printf(%d块:%d\t,i+1,bitPointer-bitMap[i]);}printf(\n);}voidshowFile(){printf(磁盘文件:);if(bitPointer-fileTag[0]!=)printf(%s,bitPointer-fileTag[0]);for(inti=1;iCOUNT;i++){if(strcmp(bitPointer-fileTag[i-1],bitPointer-fileTag[i])!=0&&bitPointer-fileTag[i]!=)printf(%s,bitPointer-fileTag[i]);}printf(\n);}voiddiskAlloc(void){intneedNum;inti;intbusy=0;charfile[32];printf(输入需要分配的块数:\n);scanf(%d,&needNum);for(i=0;iCOUNT;i++)busy=busy+bitPointer-bitMap[i];if(64-busyneedNum)printf(没有足够的空闲磁盘,分配失败!);else{printf(输入文件名:\n);scanf(%s,file);printf(开始分配...\n);for(i=0;iCOUNT;i++){if(bitPointer-bitMap[i]==0){printf(分配块物理地址为:%d柱面,%d磁道,%d扇区\n,i/SECTOR_PER_CYLINDER,i%SECTOR_PER_CYLINDER/SECTOR_PER_TRACK,(i%SECTOR_PER_CYLINDER)%SECTOR_PER_TRACK);bitPointer-bitMap[i]=1;strcpy(bitPointer-fileTag[i],file);needNum--;}if(needNum==0)break;}printf(分配成功!\n);}system(pause);}voiddiskCycle(){charfileCycle[32];inti;printf(输入要回收的文件名:);scanf(%s,fileCycle);for(i=0;iCOUNT;i++){if(strcmp(fileCycle,bitPointer-fileTag[i])!=0)continue;else{bitPointer-bitMap[i]=0;memset(bitPointer-fileTag[i],0,sizeof(char)*32);printf(回收位示图中第%d字节的第%d位的物理块\n,i/8+1,i%8+1);}}if(i==COUNT)printf(该文件不存在,回收失败\n);system(pause);}intmain(void){intfunct;init();while(1){printf(**************用位示图管理磁盘存储空间*************\n);printf(|0:退出程序\n);printf(|1:申请分配磁盘空间\n);printf(|2:申请回收磁盘空间\n);printBitMap();showFile();printf(***************************************************\n);scanf(%d,&funct);switch(funct){case0:return0;case1:diskAlloc();break;case2:diskCycle();break;default:printf(无此操作,请重新输入:\n);}system(cls);}}