磁盘存储空间模拟管理系统 位示图方向
- 格式:doc
- 大小:98.00 KB
- 文档页数:15
第五章计算机操作系统概论复习资料习题答案第五章复习题一、单项选择题1.文件按用途分类,不包括(D)。
A.系统文件B.库文件C.用户文件D.档案文件2.一种既方便顺序存取又适合随机存取的文件存储结构是(C)。
A.顺序文件B.链接文件C.索引文件D.串联文件3.若把文件以顺序结构的方式存放到磁盘上,则存在的缺点是(B)。
A.目录结构复杂B.磁盘空间利用率低C.计算地址困难D.读写速度低4磁带上的每个文件组成部分不包括(C)。
A.文件头标B.文件信息C.文件正文D.文件尾标5.文件的信息按逻辑上独立的含义划分信息单位后就构成了记录式文件,这种划分信息的工作是(A)时完成的。
A.用户组织文件B.系统转储文件C.系统装入文件D.外设存取文件6.UNI某系统调用unlink的作用是(B)。
A.为一个文件再取一个新文件名B.删除文件的一个文件名C.请求读一个已经打开的文件D.建立两个文件的链接7.下面对目录结构描述错误的是(A)。
A.一级目录结构解决了文件的重名问题B.树形目录结构解决了文件的重名问题C.树形目录结构能进行存取权限的控制C.树形目录结构有利于文件分类8.读一个文件信息时,应依次调用(A)。
A.打开文件、读文件、关闭文件B.建立文件、读文件、关闭文件C.建立文件、读文件、写文件D.读文件、保存文件、关闭文件9.若允许用户按各自定义的文件名访问某个共享文件夹,则该系统应(C)。
A.为每个用户复制一份文件B.设置命名转换机制C.采用多级目录结构D.使该文件有多种物理结构形式10.文件的存储结构采用哪种形式是与(C)有关。
A.文件的逻辑结构B.存储空间的管理方式C.存储介质的类型D.文件的长度11.下列选项中属于存储介质的是(C)。
A.磁带机B.磁盘驱动器C.软磁盘片D.卡片机12.实现记录的成组与分解能提高磁盘空间的利用率,但必须设置主存缓冲区,该缓冲区的长度应根据(A)来确定。
A.磁盘块的大小B.成组的记录数C.逻辑记录的长度D.文件的长度13.对记录式文件,操作系统为用户存取文件信息的最小单位是(C)。
操作系统文件存储空间管理位示图法#include#include#include#includeusing namespace std;struct FCB{char fname[16]; //文件名int type; //1代表普通文件2代表目录文件0表示空文件int size; //文件大小int fatherBlockNum; //当前的父目录盘块号int firstBlockNum; //该文件第一个盘块号int currentBlockNum; //当前的盘块int lastBlockNum;void initialize(){strcpy(fname,"\0");type = 0;size =0;fatherBlockNum = firstBlockNum = currentBlockNum =lastBlockNum= 0; }};/*常量设置*/const char* FilePath = "C:\\myfiles";const int BlockSize = 512; //盘块大小(可配置)const int OPEN_MAX = 5; //能打开最多的文件数const int BlockCount = BlockSize/sizeof(int); //盘块数const int DiskSize = BlockSize*BlockCount; //磁盘大小const int BlockFcbCount = BlockSize/sizeof(FCB);//目录文件的最多FCB数const int m=16; //位示图的列数const int n=BlockCount/m; //位示图的行数//const int IOBUF_SIZE = 512;//char IOBuffer[IOBUF_SIZE];int OpenFileCount = 0;struct OPENLIST //用户文件打开表{int files; //当前打开文件数FCB f[OPEN_MAX]; //FCB拷贝OPENLIST(){files=0;for(int i=0;i<open_max;i++){< bdsfid="106" p=""></open_max;i++){<>f[i].fatherBlockNum=-1;//为分配打开f[i].type=0;}}};/*-------------目录文件结构---------------*/struct dirFile{struct FCB fcb[BlockFcbCount];void init(int _FatherBlockNum,int _FirstBlockNum, int _CurrentBlockNum,int _LastBlockNum,char *name)//父块号,第一个盘块号,当前块号,目录名{strcpy(fcb[0].fname,name); //本身的FCBfcb[0].fatherBlockNum=_FatherBlockNum;fcb[0].firstBlockNum=_FirstBlockNum;fcb[0].currentBlockNum=_CurrentBlockNum;fcb[0].lastBlockNum=_LastBlockNum;fcb[0].type=2; //标记目录文件for(int i=1;i<blockfcbcount;i++)< bdsfid="125" p=""></blockfcbcount;i++)<>{fcb[i].fatherBlockNum=_CurrentBlockNum; //标记为子项fcb[i].type=0; // 标记为空白项}}};/************************************************************** ********/struct DISK{int FAT1[BlockCount]; //FAT1int FAT2[BlockCount]; //FAT2struct dirFile root; //根目录int map[n][m]; //位示图,最初都为0int check[n][m]; //check数组用于一致性检查,作为数据计数器;char data[BlockCount-5][BlockSize];void format(){memset(FAT1,0,BlockCount); //FAT1memset(FAT2,0,BlockCount); //FAT2FAT1[0]=FAT1[1]=FAT1[2]=FAT1[3]=FAT1[4]=-2; //0,1,2盘块号依次代表FAT1,FAT2,根目录区FAT2[0]=FAT2[1]=FAT2[2]=FAT2[3]=FAT2[4]=-2; //FAT作备份root.init(2,2,2,2,"G:\\");//根目录区for(int i=0;i<=BlockCount;i++) //map[0][0],map[0][1],map[0][1],map[0][2],map[0][3],map[0][4]以及check{ //对应位置为占用if(i<5){map[0][i]=0;check[0][i]=1;}else{map[i/16][i%16]=1;check[i/16][i%16]=0;}}memset(data,0,sizeof(data));//数据区}};/*-----------------全局变量--------------------------*/FILE *fp; //磁盘文件地址char * BaseAddr; //虚拟磁盘空间基地址string currentPath="G:\\"; //当前路径int current=2; //当前目录的盘块号string cmd; //输入指令struct DISK *osPoint; //磁盘操作系统指针char command[16]; //文件名标识struct OPENLIST* openlist; //用户文件列表指针/*-----------函数事先申明--------------------*/int format();int mkdir(char *sonfname);int rmdir(char *sonfname);int create(char *name);int listshow();int delfile(char *name);int changePath(char *sonfname);int write(char *name);int exit();int open(char *file);int close(char *file);int read(char *file);/*------------初始化-----------------------*/int format(){current = 2;currentPath="G:\\"; //当前路径osPoint->format();//打开文件列表初始化delete openlist;openlist=new OPENLIST;/*-------保存到磁盘上myfiles--------*/fp = fopen(FilePath,"w+");fwrite(BaseAddr,sizeof(char),DiskSize,fp);fclose(fp);printf("----------------------------------------------------------\n\n"); return 1;}/*-----------------------创建子目录-------------------*/int mkdir(char *sonfname){//判断是否有重名//寻找空白子目录项//寻找空白盘块号//当前目录下增加该子目录项//分配子目录盘块,并且初始化//修改fat表int i,temp,iFAT;struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);/*--------为了避免该目录下同名文件夹--------*/for(i = 1;i<blockfcbcount;i++)< bdsfid="216" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 ) {printf("该文件夹下已经有同名的文件夹存在了!\n");return 0;}}//查找空白fcb序号for(i=1;i<blockfcbcount;i++)< bdsfid="225" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==0)break;}if(i==BlockFcbCount){printf("该目录已满!请选择新的目录下创建!\n");return 0;}temp=i;for(i = 5;i < BlockCount;i++){if(osPoint->map[i/m][i%m] > 0)break;}if(i == BlockCount){printf("磁盘已满!\n");return 0;}iFAT=i;/*-------------接下来进行分配----------*/osPoint->map[iFAT/m][iFAT%m]--; //对应盘块在位示图置0;osPoint->FAT1[iFAT]=osPoint->FAT2[iFAT]= iFAT; //每个目录文件只占一块所以在文件分配表中其链接的下一块为其本身osPoint->check[iFAT/m][iFAT%m]++; //对应盘块在数据计数器中置1;//填写该分派新的盘块的参数strcpy(dir->fcb[temp].fname,sonfname);dir->fcb[temp].type=2;dir->fcb[temp].fatherBlockNum=current;dir->fcb[temp].firstBlockNum=iFAT;dir->fcb[temp].currentBlockNum=iFAT;dir->fcb[temp].lastBlockNum=iFAT;//初始化子目录文件盘块dir=(struct dirFile*)(osPoint->data [iFAT-5]); //定位到子目录盘块号dir->init (current,iFAT,iFAT,iFAT,sonfname);//iFAT是要分配的块号,这里的current用来指要分配的块的父块号printf("---------------------------------------------------------------\n\n");return 1;}/*-------删除当前目录下的文件夹--------*/int rmdir(char *sonfname){//if(子目录不存在) return error//if(子目录不是空文件夹) return error//回收子目录磁盘块号b(修改fat)//回收子目录占据目录项int i,temp,j;//确保当前目录下有该文件,并记录下该FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);for(i=1;i<blockfcbcount;i++)< bdsfid="277" p=""></blockfcbcount;i++)<>{ //查找该目录文件if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0){break;}}temp=i;if(i==BlockFcbCount){printf("当前目录下不存在该子目录!\n");return 0;}j = dir->fcb[temp].currentBlockNum;struct dirFile *sonDir; //当前子目录的指针sonDir=(struct dirFile *)(osPoint->data [ j - 5]);for(i=1;i<="">{if(sonDir->fcb[i].type!=0){printf("该文件夹为非空文件夹,为确保安全,请清空后再删除!\n");return 0;}}/*开始删除子目录操作*/osPoint->FAT1[j] = osPoint->FAT2[j]=0; //fat清空osPoint->map[j/m][j%m]++; //位示图对应盘块置为空闲osPoint->check[j/m][j%m]--; //数据计数器对应盘块置为空闲char *p=osPoint->data[j-5]; //格式化子目录memset(p,0,BlockSize);dir->fcb[temp].initialize(); //回收子目录占据目录项printf("---------------------------------------------------------------\n\n"); return 1;}/*-----------在当前目录下创建文本文件---------------*/int create(char *name){int i,iFAT;//temp,int emptyNum = 0,isFound = 0; //空闲目录项个数struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);//查看目录是否已满//为了避免同名的文本文件for(i=1;i<blockfcbcount;i++)< bdsfid="322" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type == 0 && isFound == 0){emptyNum = i;isFound = 1;}else if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0 ) {printf("无法在同一目录下创建同名文件!\n");return 0;}}if(emptyNum == 0){printf("已经达到目录项容纳上限,无法创建新文件!\n");return 0;}//查找位示图寻找空白区,用来分配磁盘块号jfor(i = 5;i<blockcount;i++)< bdsfid="341" p=""></blockcount;i++)<>{if(osPoint->map[i/m][i%m] > 0)break;}if(i==BlockCount){printf("磁盘已满!\n");return 0;}iFAT=i;/*------进入分配阶段---------*///位示图分配osPoint->map[iFAT/m][iFAT%m]--;//分配磁盘块osPoint->FAT1[iFAT] = osPoint->FAT2[iFAT] = iFAT; //文件刚刚创建时只分配一块FAT连接自身//数据计数器对应位置为占用osPoint->check[iFAT/m][iFAT%m]++;/*-----------接下来进行分配----------*///填写该分派新的盘块的参数strcpy(dir->fcb[emptyNum].fname,name);dir->fcb[emptyNum].type=1;dir->fcb[emptyNum].fatherBlockNum=current;dir->fcb[emptyNum].firstBlockNum=iFAT;dir->fcb[emptyNum].currentBlockNum=iFAT;dir->fcb[emptyNum].lastBlockNum=iFAT;dir->fcb[emptyNum].size =0;char* p = osPoint->data[iFAT -5];memset(p,'#',BlockSize);printf("----------------------------------------------------------------\n\n");return 1;}/*-------查询子目录------------*/int listshow(){int i,DirCount=0,FileCount=0;//搜索当前目录struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);for(i=1;i<blockfcbcount;i++)< bdsfid="384" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==1){ //查找普通文件FileCount++;printf("%s 文本文件.\n",dir->fcb[i].fname);}if(dir->fcb[i].type==2){ //查找目录文件DirCount++;printf("%s 文件夹.\n",dir->fcb[i].fname);}}printf("\n该目录下共有%d 个文本文件, %d 个文件夹\n\n",FileCount,DirCount); printf("--------------------------------------------------------\n\n");return 1;}/*---------在当前目录下删除文件-----------*/int delfile(char *name){int i,temp,j;//确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);for(i=1;i<="">{if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0){break;}}if(i==BlockFcbCount){printf("当前目录下不存在该文件!\n");return 0;}//从打开列表中删除close(name);printf("文件已删除!\n");temp=i;/*开始删除文件操作*/dir->fcb [temp].currentBlockNum=dir->fcb [temp].firstBlockNum;int next=dir->fcb [temp].currentBlockNum ;//查找盘块号jdo{j = dir->fcb [temp].currentBlockNum = next;next=osPoint->FAT1[j];osPoint->FAT1[j]=osPoint->FAT2[j]=0; //fat1,fat2表标记为空白osPoint->map[j/m][j%m]++; //位示图该盘块号对应位置为空闲osPoint->check[j/m][j%m]--; //数据计数器对应盘块号置为空闲char *p=osPoint->data[j - 5];memset(p,0,BlockSize); //清除原文本文件的内容}while(dir->fcb [temp].currentBlockNum!=dir->fcb [temp].lastBlockNum);dir->fcb[temp].initialize(); //type=0; //标记该目录项为空文件printf("------------------------------------------------------------\n\n");return 1;}/*--------------进入当前目录下的子目录--------------*/int changePath(char *sonfname){struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);/*回到父目录*/if(strcmp(sonfname,"..")==0){if(current==2){printf("你现已经在根目录下!\n");return 0;}current = dir->fcb[0].fatherBlockNum ;currentPath = currentPath.substr(0,currentPath.size() - strlen(dir->fcb[0].fname )-1); return 1;}/*进入子目录*/int i,temp;//确保当前目录下有该目录,并且记录下它的FCB下标for(i = 1; i < BlockFcbCount; i++){ //查找该文件if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 ) {temp=i;break;}}if(i==BlockFcbCount){printf("不存在该目录!\n");return 0;}//修改当前文件信息current=dir->fcb [temp].currentBlockNum ;currentPath = currentPath+dir->fcb [temp].fname +"\\";printf("-------------------------------------------------------------\n\n"); return 1;}/*--------System exit---------------------*/int exit(){//将所有文件都关闭//保存到磁盘上C:\myfilesfp=fopen(FilePath,"w+");fwrite(BaseAddr,sizeof(char),DiskSize,fp);fclose(fp);//释放内存上的虚拟磁盘free(osPoint);//释放用户打开文件表delete openlist;printf("---------------------------------------------------------\n\n");return 1;}/*-------------在指定的文件里记录信息---------------*/int write(char *name){int i;int iFAT;int FcbIndex;char *startPoint,*endPoint;struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况)for(i=0;i<open_max;i++)< bdsfid="514" p=""></open_max;i++)<>{if(strcmp(openlist->f [i].fname,name)==0 ){if(openlist->f[i].fatherBlockNum ==current){break;}else{printf("该文件处于打开列表中,本系统只能改写当前目录下文件!\n");return 0;}}}if(i==OPEN_MAX){printf("该文件尚未打开,请先打开后写入信息!!\n");return 0;}int active=i;for(i = 1;i< BlockFcbCount;i++){ //查找该文件if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0 )FcbIndex=i;break;}}openlist->f[active].currentBlockNum=openlist->f[active].firs tBlockNum; int next=openlist->f[active].currentBlockNum;int now;while(next!=openlist->f[active].lastBlockNum){now=openlist->f[active].currentBlockNum;next=osPoint->FAT1[now];osPoint->map[next/m][next%m]++;osPoint->check[next/m][next%m]--;}int fileStartNum = openlist->f[active].currentBlockNum - 5 ; startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];printf("请输入文本以#号结束:\t");char input;while((input=getchar())!='#'){if(startPoint < endPoint){*startPoint++ = input;}else{for(i = 5;i<blockcount;i++)< bdsfid="565" p=""></blockcount;i++)<>if(osPoint->map[i/m][i%m] > 0)break;}if(i==BlockCount){printf("磁盘已满!\n");*--startPoint='#';return 0;iFAT=i;now=openlist->f[active].currentBlockNum;osPoint->map[iFAT/m][iFAT%m]--;osPoint->check[iFAT/m][iFAT%m]++;osPoint->FAT1[now]= osPoint->FAT2[now]=iFAT;openlist->f[active].currentBlockNum=iFAT;char* p = osPoint->data[iFAT -5];memset(p,'#',BlockSize);int fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];*startPoint++ = input;}}openlist->f[active].lastBlockNum=openlist->f[active].current BlockNum;dir->fcb[FcbIndex].lastBlockNum=openlist->f[active].curren tBlockNum; return 1;}/*---------选择一个打开的文件读取信息----------*/int read(char *file)int i,fileStartNum;char *startPoint,*endPoint;//struct dirFile *dir;//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况)for(i=0;i<open_max;i++)< bdsfid="600" p=""></open_max;i++)<>{if(strcmp(openlist->f [i].fname,file)==0 ){if(openlist->f[i].fatherBlockNum ==current){break;}else{printf("该文件处于打开列表中,本系统只能阅读当前目录下文件!\n");return 0;}}if(i==OPEN_MAX){printf("该文件尚未打开,请先打开后读取信息!\n");return 0;}int active=i;int now;//计算文件物理地址openlist->f[active].currentBlockNum=openlist->f[active].firs tBlockNum; fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];//end_dir=(struct dirFile *)[BlockSize-1];//q=(char *)end_dir;printf("该文件的内容为: ");while((*startPoint)!='#'){if(startPoint<endpoint-1)< bdsfid="631" p=""></endpoint-1)<>putchar(*startPoint++);else{putchar(*startPoint);now=openlist->f[active].currentBlockNum;openlist->f[active].currentBlockNum=osPoint->FAT1[now];fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];}}printf("\n");return 1;}/*---------------当前目录下添加一个打开文件-------------------------*/int open(char *file)//打开文件{int i,FcbIndex;//确保没有打开过该文件= 相同名字+ 相同目录for(i=0;i<open_max;i++)< bdsfid="652" p=""></open_max;i++)<>{if(openlist->f[i].type ==1 && strcmp(openlist->f [i].fname,file)==0 &&openlist->f[i].fatherBlockNum == current){printf("该文件已经被打开!\n");return 0;}}//确保有空的打开文件项if(openlist->files == OPEN_MAX){printf("打开文件数目达到上限!无法再打开新文件.\n");return 0;}//确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);for(i = 1;i< BlockFcbCount;i++){ //查找该文件if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,file)==0 ) {FcbIndex=i;break;}}if(i==BlockFcbCount){printf("当前目录下不存在该文件!\n");return 0;}//装载新文件进入打开文件列表,(FCB信息,文件数++)openlist->f[OpenFileCount] = dir->fcb[FcbIndex]; //FCB拷贝openlist->files ++;printf("文件打开成功!\n");OpenFileCount++;return 1;}int close(char *file){//释放该文件所占内存//释放用户打开文件列表表项int i;//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况) for(i=0;i<open_max;i++)< bdsfid="698" p=""></open_max;i++)<>{if((openlist->f [i].type = 1)&&(strcmp(openlist->f [i].fname,file)==0)){if(openlist->f[i].fatherBlockNum == current){break;}else{printf("该文件已打开,但未在当前目录下,无法关闭!\n"); return 0;}}}if(i==OPEN_MAX){。
1. 操作系统结构设计应追求的目标是什么?正确性、高效性、维护性、移植性。
2. 在磁盘存储空间管理的位示图法中,确定已知空闲块地址的块号、柱面号的通用公式为:块号=字号×字长+位号柱面号=\[块号/柱面上的块数\]请写出确定空闲块地址的磁头号和扇区号的通用公式。
答案:磁头号=\[(块号mod柱面上的块数)/盘面上的扇区数\]扇区号=(块号mod柱面上的块数)mod盘面上的扇区数3. UNIX系统调用close是如何处理的?清除有关的表项。
检查块设备的缓冲区是否还有信息未写回,若有,则写回设备。
检查是否有其他进程仍打开此设备,若有,则不能关闭此设备。
若无其他进程打开此设备,调用驱动程序中的关闭过程,与设备断开。
4. 什么是线程?简述进程与线程的关系。
线程是进程中可独立执行的子任务。
一个进程中可以有一个或多个线程。
一个进程中的各个线程可以并发执行。
系统为进程分配主存空间,同一进程中的各线程共享该进程的主存空间。
5. 操作系统采用层次结构设计方法有什么优点和难点?主要优点是有利于系统的设计与调试,主要困难在于层次的划分和安排。
6. 目录结构有一级、二级和树形目录结构。
请简单叙述树形目录结构的优点。
解决了重名问题;有利于文件分类;提高检索文件的速度;能进行存取权限的控制。
7. 简述UNIX中系统调用命令OPEN的处理过程。
(1)分配一个活动索引节点,引用计数i_count加1。
(2)在进程打开文件表和系统打开文件表中分配表项。
(3)调用设备驱动程序检查打开的合法性。
(4)初始化驱动程度的数据结构。
(5)建立进程和设备间的联系。
8. 比较进程同步和进程互斥的异同。
答案:同:两者都是对并发进程竞争共享资源的管理。
异:进程互斥——各进程竞争共享资源没有必然的逻辑顺序。
只要无进程在使用共享资源就允许任一进程去使用。
进程同步——对共享资源的使用有一定的逻辑顺序。
9. 某系统有同类资源m个,供n个进程共享,如果每个进程最多申请x(1≤x≤m)个资源,且各进程的最大需求量之和小于(m+n)个资源,证明该系统不会发生死锁。
袇课程设计报告螈(2016--2017年度第二学期):操作系统实验薆课程名称:用位示图管理磁盘空间的分配与回收袃课设题目:控制与计算机工程学院羇院系:信安1401羅班级:黄竞昶羃姓名:贾静平薂指导教师:一周肇设计周数:莆成绩年 7月 9日螅2015莀一、需求分析蒁要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
螆( 1)假定现有一个磁盘组,共 40 个柱面。
每个柱面 4 个磁道,每个磁道又划分成 4 个物理记录。
磁盘的空间使用情况用位示图表示。
位示图用若干个字构成,每一位对应一个磁盘块。
1 表示占用, 0 表示空闲。
为了简单,假定字长为 16 位,其位示图如图 9— 1 所示。
系统设一个变量 S,记录磁盘的空闲块个数。
莃蒁 1 膇 2 袅 3 膂 4 薁 5 薈 6 莃 7 羁 8 蚀 9 蚅肅蚀螀肆薃膃位10 11 12 13 14 15袀螃字 0 蒇 1 芅 1 薂 1 羀 1 袈 1 蚂 0 芁 1 肀 0 羄 0 莄 1 聿 1 肀 1 莅 1 袂 1 肂 01膀 1袆 2....袁 39芀图 9—1 位示图( 2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0 的位,并计算磁盘的芇物理地址 ( 即求出柱面号、磁道号 ( 也即磁头号 ) 和扇区号 ) 。
肂由位示图计算磁盘的相对块号的公式如下:蚀相对块号一字号× 16+位号荿之后再将相对块号转换成磁盘的物理地址:蚈由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4× 4= 16,故柱面号=相对块号/ 16 的商,即柱面号=字号螄磁道号= ( 相对块号/ 16 的余数 ) /4 的商,即 ( 位号/ 4) 的商蚃物理块号= ( 相对块号/ 16 的余数 ) / 4 的余数,即 ( 位号/ 4) 的余数葿( 3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置 0。
合肥学院计算机科学与技术系课程设计报告20011~2012 学年第1 学期课程名称操作系统原理课程设计名称模拟实现用位示图法管理文件存储空间的分配与回收专业班级学生姓名学生学号指导教师20011 年11 月实验题目模拟用位示图法管理文件存储空间的分配与回收一、实验目的:1)理解文件存储空间的分配与回收的基本概念,掌握产生文件存储空间的分配与回收的几种方法,体会位示图算法是管理文件存储空间的分配与回收的一种行之有效的方法。
2)通过编写程序实现位示图算法,进一步理解位示图算法的原理和执行过程,掌握位示图算法的描述和应用,进一步熟练掌握文件存储空间的分配与回收的方法。
二、实验内容:(1)首先对位示图算法原理进行深刻的理解和掌握;(2)程序首先要给出位示图初态。
分配时,参数为文件名及需要分配的块数。
回收时,参数为文件名。
(3)回答信息:分配时,能够分配时,给出文件名和分配的具体块号。
否则,给出无法分配的信息。
显示位示图。
(4)回收时:给出回收的具体块号。
显示位示图。
三、实验环境Windows系统,在C++的环境下来运行这儿程序四、实验主要步骤1、初始化及使用数据结构对数组WST[]元素初始化为0。
定义以下3个链表并初始化。
空闲区结构体定义free_link、申请空间作业结构体定义office、相关位示图操作的结构体定义work。
位示图算法是利用二进制的一位来表示磁盘中的一个盘块的使用情况。
在外存上建立一张位示图(bitmap),记录文件存储器的使用情况。
每一位仅对应文件存储器上的一个物理块,取值0和1分别表示空闲和占用。
文件存储器上的物理块依次编号为:0、1、2、…。
定义为一维数组WST[],操作起来更为方便。
下表号与盘块号对应。
在输出的时候控制输出为二维形式。
2、申请空间算法首先要输入文件名和大小,查找与已存在的文件是否重名。
没有,则比较空闲区中空闲块数是否大于欲分配的块数。
有的话分配。
分配的时候该作业要记录下自己所占盘块的其实盘号和所占用的盘快数。
操作系统-阶段测评31. 单选题1.1 3.0下面对移臂调度算法的描述错误的是(d)您答对了«a移臂调度的目的是减少寻找时间,包括先来先服务、最短寻找时间优先、电梯调度、单向扫描等算法* b先来先服务调度算法不考虑访问要求的物理位置,只考虑提出请求的先后次序* c最短寻找时间优先、电梯调度和单向扫描算法根据访问请求的柱面位置调度«d相比之下先来先服务调度算法是最简单实用且花费时间短的算法1.2 3.0下列关于SPOOLIN(系统的说法不正确的是(d)您答错了* aSPOOLING是Simultaneous Peripheral Operation On Line 的缩写,又称斯普林系统* bSPOOLIN係统由预输入程序、井管理程序和缓输出程序三部分组成* c操作系统实现虚拟设备的功能模块是在计算机控制下通过联机的外围设备同时操作来实现其功能的* dSPOOLIN(系统是一种类似于通道的硬件设备,是实现独占设备与共享设备的映射1.3 3.0磁盘上的某个磁道被划分成四块,磁盘的转速为20毫秒/转,当前磁头在第二块的开始位置,则花费(b)毫秒的时间可把第一块信息读到主存。
(假设旋转是按由块号从小到大方向的)您答对了«a40«b20* c10* d51.4 3.0对磁盘而言,输入输出操作的信息传送单位为:(b)您答对了* a字符* b块文件考察I/O的信息传递单位。
1.5 3.0在通道结构中,操作系统启动和控制外围设备完成输入/输出操作的过程(a)您答对了* a包括准备、启动I/O和结束处理三个阶段* b包括启动、选择通道和设备、控制设备处理输入/输出操作和完成处理几个步骤* c包含启动I/O等特权准备,是一种访管中断,属于强迫性中断事件* d不属于“设备处理一致性”的处理方法本题考查的知识点为输入/输出操作控制。
操作系统启动和控制外围设备完成输入/输出操作的过程可分为以下三个阶段:(1)准备阶段。
合肥学院计算机科学与技术系课程设计报告20011~2012 学年第1 学期课程名称操作系统原理课程设计名称模拟实现用位示图法管理文件存储空间的分配与回收专业班级学生姓名学生学号指导教师20011 年11 月实验题目模拟用位示图法管理文件存储空间的分配与回收一、实验目的:1)理解文件存储空间的分配与回收的基本概念,掌握产生文件存储空间的分配与回收的几种方法,体会位示图算法是管理文件存储空间的分配与回收的一种行之有效的方法。
2)通过编写程序实现位示图算法,进一步理解位示图算法的原理和执行过程,掌握位示图算法的描述和应用,进一步熟练掌握文件存储空间的分配与回收的方法。
二、实验内容:(1)首先对位示图算法原理进行深刻的理解和掌握;(2)程序首先要给出位示图初态。
分配时,参数为文件名及需要分配的块数。
回收时,参数为文件名。
(3)回答信息:分配时,能够分配时,给出文件名和分配的具体块号。
否则,给出无法分配的信息。
显示位示图。
(4)回收时:给出回收的具体块号。
显示位示图。
三、实验环境Windows系统,在C++的环境下来运行这儿程序四、实验主要步骤1、初始化及使用数据结构对数组WST[]元素初始化为0。
定义以下3个链表并初始化。
空闲区结构体定义free_link、申请空间作业结构体定义office、相关位示图操作的结构体定义work。
位示图算法是利用二进制的一位来表示磁盘中的一个盘块的使用情况。
在外存上建立一张位示图(bitmap),记录文件存储器的使用情况。
每一位仅对应文件存储器上的一个物理块,取值0和1分别表示空闲和占用。
文件存储器上的物理块依次编号为:0、1、2、…。
定义为一维数组WST[],操作起来更为方便。
下表号与盘块号对应。
在输出的时候控制输出为二维形式。
112、申请空间算法首先要输入文件名和大小,查找与已存在的文件是否重名。
没有,则比较空闲区中空闲块数是否大于欲分配的块数。
有的话分配。
分配的时候该作业要记录下自己所占盘块的其实盘号和所占用的盘快数。
用位图法模拟管理文件存储空间分配和恢复的实现。
计算机科学与技术学院《操作系统》综合测试报告(XXXX第一学期)学生姓名:学生专业:网络工程学生班:网络班级学生人数:2名教员:12月12日,计算机科学与技术学院综合测试任务书课程设计名称《操作系统》课程设计课程设计主题模拟实现文件存储空间分配和恢复管理与位置映射方法学生姓名专业课网络编号2综合测试任务内容[问题描述]综合应用程序设计实现。
内容如下:(1)首先,我们应该深刻理解和掌握映射算法的原理。
(2)程序必须首先给出位图的初始状态。
在分配期间,参数是文件名和要分配的块数。
回收时,参数是文件名。
(3)回答信息: 当可以分配时,给出文件名和要分配的特定块号。
否则,将给出无法分配的信息。
显示位图。
(4)回收时:给出具体的回收块数。
显示位图。
[基本要求] (1)了解文件存储空间分配和恢复的基本概念,掌握几种生成文件存储空间分配和恢复的方法,认识到位图算法是管理文件存储空间分配和恢复的有效方法。
(2)通过编写程序实现位图算法,可以进一步了解位图算法的原理和执行过程,掌握位图算法的描述和应用,进一步掌握文件存储空间的分配和恢复方法。
[测试要求]对每个模块的功能进行黑盒测试,确保每个模块功能的正确性。
讲师:时间:2005年1月5日目录第一章功能需求描述11.1功能列表和描述11.2操作界面11.3界面操作1第二章系统设计描述22.1任务分解描述22.2主要数据结构设计描述22.3主要功能界面描述2第三章算法设计描述53.1主要功能和功能流程图53.1.1磁盘块分配算法流程图5 3.2.2。
磁盘块恢复算法流程图6第4章开发过程描述74.1程序源代码74.2程序中遇到的错误和错误原因74.3用于测试程序功能和测试方法的数据7第5章设计经验8附录1程序源代码9字模型第1章功能要求描述1.1功能列表和描述功能名称描述分发文件分发恢复文件退出程序1.2操作接口文件的访问和恢复1 .分发文件2 .恢复文件3。
课程设计报告( 2016--2017年度第二学期)课程名称:操作系统实验课设题目: 用位示图管理磁盘空间的分配与回收院系:控制与计算机工程学院班级:信安1401姓名:黄竞昶指导教师:贾静平设计周数: 一周成绩:2015年7月9 日一、需求分析要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
(1)假定现有一个磁盘组,共40个柱面。
每个柱面4个磁道,每个磁道又划分成4个物理记录。
磁盘的空间使用情况用位示图表示。
位示图用若干个字构成,每一位对应一个磁盘块。
1表示占用,0表示空闲。
为了简单,假定字长为16位,其位示图如图9—1所示。
系统设一个变量S,记录磁盘的空闲块个数。
图9—1 位示图(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。
由位示图计算磁盘的相对块号的公式如下:相对块号一字号×16+位号之后再将相对块号转换成磁盘的物理地址:由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。
计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号×16+磁道号×4+物理块号 再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号 位号=磁道号×物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。
然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。
(5)设计一个回收算法,将上述已分配给用户的各盘块释放。
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2013年秋季学期
操作系统课程设计
题目:磁盘空间管理模拟实验
专业班级:计算机科学与技术11级4班
姓名:刘文清
学号:11240425
指导教师:李明
成绩:
目录
摘要 (2)
1.设计思想 (3)
2.算法设计 (4)
3.源程序 (6)
4.运行结果 (10)
5.总结 (13)
参考文献 (13)
摘要
要把文件信息存放在存储介质上,必须先找出存储介质上可供使用的空闲块。
存储介质上某个文件不再需要时,又要收回它所占的存储空间作为空闲块。
用户作业在执行期间经常要求建立一个新文件或撤消一个不再需要的文件,因此,文件系统必须要为它们分配存储空间或收回它所占的存储空间。
如何实现存储空间的分配和收回,取决于对空闲块的管理方法,此系统采用的对磁盘存储空间的分配和收回的方法是:位示图法(用一张位示图(简称位图)来指示磁盘存储空间的使用情况)。
此磁盘存储模拟管理系统采用C++语言实现的,其运行环境是Windows xp,Windows 7操作系统。
关键词:磁盘的分配和回收管理;位示图,磁盘存储空间管理。
1.设计思想
在Windows XP,Windows 7等操作系统中对磁盘存储空间的管理是位示图法,位示图法:一个简单的管理方法,是用一张位示图(简称位图)来指示磁盘存储空间的使用情况。
一个盘组的分块确定后,根据分配的总块数决定位图由多少个字组成,建筑位图中的每一位与盘组分块1-1对应,“1”状态表示相应块已占用,“0”状态表示该块空闲。
在分配时先查看要分配的位置的数值,若其值为0,则分配,否则不予分配,输出此空间已被占用;在释放时分别找到柱面号,磁道号和扇区号所对应的在位示图中的位置,进行释放,若其值为0,则表示为分配,若其值为1,则变为0,回收完成。
2.算法设计
数据结构如下:
unsigned int size[5]={1,1,1,1,1} ;/*保存位示图*/ 算法流程图如下:
分配流程图如下图2-1:
图2-1
回收空间流程图如下:
否
图2-2
3.源程序
位示图法算法如下:
#include<stdio.h>
unsigned int size[5]={1,1,1,1,1} ;/*保存位示图*/
void out()/*输出位示图函数*/
{ unsigned int i,j,m;
for(j=0;j<5;j++)/*循环输出size的各个数的各个二进制位*/ {m=size[j];
for(i=0;i<16;i++)/**/
{printf("%d ",m%2);
m=m/2;
if(i==7)
printf("\n");
}
printf("\n");
}
}
void callback()/*回收函数*/
{ unsigned int i,j,k,s=1,q,m,sq,zhm,cid;
printf("确定要回收块的柱面号、磁道号、扇区号:\n");
printf("请输入柱面号:");
scanf("%d",&zhm);
printf("\n请输入磁道号:");
scanf("%d",&cid);
printf("\n请输入扇区号:");
scanf("%d",&sq);
if(zhm%2==0)/*计算对应的位示图位置*/
{ i=zhm/2;
j=cid*4+sq+1;
}
else
{ i=(zhm-1)/2;
j=cid*4+sq+9;
}
q=size[i];
m=j-1;
while(m)
{q=q/2;
m--;}
if(q%2==1)/*判断该块是否被分配*/
{if(j==1)size[i]-=1;/*将位示图对应为置零*/ else
{for(m=1;m<j;m++)
s*=2 ;
size[i]-=s;}
printf("回收成功!");
printf("回收后的位示图为:\n");
out();
}
else
printf("该块以被分配!");
}
void assign()/*分配函数*/
{ unsigned int n=0,i,s=1,j,k,q,m,sq,zhm,cid;
for(i=0 ,k=0;i<5;i++)
{ q=size[i] ;
j=0;
while(1) /*查找位示图的第一个为零的位,将其分配,该位置一*/
{ j++ ;
if((q%2)==0)
{ if(j==1) size[i]+=1;
else
{for(m=1;m<j;m++)
s*=2 ;
size[i]+=s;}
k=1;
break ;/*完成后退出*/
}
q=q/2;
}
if(k==1) /*将找到的位示图位转换成物理地址*/
{ if((j-1)/8==1)
{zhm=2*i+1;
cid=(j-9)/4;
sq=(j-9)%4;}
else
{zhm=2*i;
cid=(j-1)/4;
sq=(j-1)%4;
}
n=1;
break;/*退出for循环*/
}
}
if(n==0)
printf("没有空间可分配!\n");
else
{printf("分配成功!\n");/*输出物理地址*/ printf("柱面号为: %d\n",zhm);
printf("磁道号为: %d\n",cid);
printf("扇区号为: %d\n",sq);
}
printf("分配后的位示图为:\n");
out();
}
void menu() /*功能选择函数*/
{ int choice;
char judge;
printf("\n请选择操作:(1--分配,2--回收):"); scanf("%d",&choice);
getchar();
if(choice==1)
assign();
else if(choice==2)
callback();
else
printf("\n没有此项!");
printf("\n继续还是退出?(y--继续,n--退出):"); scanf("%c",&judge);
getchar();
if(judge=='y')
menu();
else
{ printf("\n现在的位示图:\n");
out();
printf("\n按任意键退出!\n");
getchar();
}
}
main()
{
out();
menu();
}
4.运行结果
下图4-1为用位示图法分配一个磁盘空间后的状态图:
下图4-2为用位示图法回收一个已分配的磁盘空间后的状态图:
图4-2位示图法回收操作运行结果
5.总结
做课程设计是为了对平时学习的理论知识与实际操作相结合,在理论和实践上进一步巩固已学基本理论及应用知识并加以综合提高,学会将知识应用于实际的方法,提高分析和解决问题的能力。
在做课程设计的过程中,深深感觉到自身所学知识的有限。
有些题目书本上没有提及,所以就没有去研究过,做的时候突然间觉得自己真的有点无知,虽然现在去看依然可以解决问题,但还是浪费了许多,这一点是必须在以后的学习中加以改进的地方,同时也要督促自己在学习的过程中不断的完善自我。
在设计过程中的思考和讨论,对现有知识能够运用计算机来解决现实生活中的实际问题确立了信心,对模块化程序设计思想有了比较清晰的印象,为今后的程序设计奠定了一定的心理和技术上的准备。
这次课程设计加强了我对计算机操作系统的认识,对我个人而言是对所学课程内容掌握情况的一次自我验证。
通过课程设计提高了我对所学知识的综合应用能力,全面检查并掌握所学的内容,培养独立思考,在分析问题、解决
问题的过程中,更是获得一种成功的喜悦。
参考文献
1.王旭阳等. 操作系统原理 [M]. 国防工业出版社, 2009
2.汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.
3.王清,李光明.《计算机操作系统》.冶金工业出版社.
4.孙钟秀等. 操作系统教程. 高等教育出版社
5.曾明. Linux操作系统应用教程. 陕西科学技术出版社.。