操作系统课程设计之请求式面页管理

时间:2019-05-14 03:02:14下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《操作系统课程设计之请求式面页管理》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《操作系统课程设计之请求式面页管理》。

第一篇:操作系统课程设计之请求式面页管理

一、目的与要求

1、目的

近年来,由于大规模集成电路(LSI)和超大规模集成电路(VLSI)技术的发展,使存储器的容量不断扩大,价格大幅度下降。但从使用角度看,存储器的容量和成本总受到一定的限制。所以,提高存储器的效率始终是操作系统研究的重要课题之一。虚拟存储技术是用来扩大内存容量的一种重要方法。学生应独立地用高级语言编写几个常用的存储分配算法,并设计一个存储管理的模拟程序,对各种算法进行分析比较,评测其性能优劣,从而加深对这些算法的了解。

任务三采用最佳淘汰算法(OPT)实现,任务四采用最近最少使用页淘汰算法(LRU)实现。

2、要求

为了比较真实地模拟存储管理,可预先生成一个大致符合实际情况的指令地址流。然后模拟这样一种指令序列的执行来计算和分析各种算法的访问命中率。

二、示例

1、题目 本示例是采用页式分配存储管理方案,并通过分析计算不同页面淘汰算法情况下的访问命中率来比较各种算法的优劣。另外也考虑到改变页面大小和实际存储器容量对计算结果的影响,从而可为算则好的算法、合适的页面尺寸和实存容量提供依据。

本程序是按下述原则生成指令序列的:(1)50%的指令是顺序执行的。

(2)25%的指令均匀散布在前地址部分。(3)25%的指令均匀散布在后地址部分。

示例中选用最佳淘汰算法(OPT)和最近最少使用页面淘汰算法(LRU)计算页面命中率。公式为

命中率1页面失效次数

页地址流长度假定虚存容量为32K,页面尺寸从1K至8K,实存容量从4页至32页。

2、算法与框图

(1)最佳淘汰算法(OPT)。这是一种理想的算法,可用来作为衡量其他算法优劣的依据,在实际系统中是难以实现的,因为它必须先知道指令的全部地址流。由于本示例中已预先生成了全部的指令地址流,故可计算出最佳命中率。

该算法的准则是淘汰已满页表中不再访问或是最迟访问的的页。这就要求将页表中的页逐个与后继指令访问的所有页比较,如后继指令不在访问该页,则把此页淘汰,不然得找出后继指令中最迟访问的页面淘汰。可见最佳淘汰算法要花费较长的运算时间。(2)最近最少使用页淘汰算法(LRU)。这是一种经常使用的方法,有各种不同的实施方案,这里采用的是不断调整页表链的方法,即总是淘汰页表链链首的页,而把新访问的页插入链尾。如果当前调用页已在页表内,则把它再次调整到链尾。这样就能保证最近使用的页,总是处于靠近链尾部分,而不常使用的页就移到链首,逐个被淘汰,在页表较大时,调整页表链的代价也是不小的。(3)程序框图如下图2所示。

产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产size=1assigned=4产产产产产产AlgAlg=OPT/LRU产OPTLRU产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产产 图2 计算页面命中率框图

3、程序运行结果格式(1)程序运行结果格式

THE VIRTUAL ADDRESS STREAM AS FOLLOWS: a[0] =16895

a[1]=16896

a[2]=16897

a[3]=16302 a[4]=25403

a[5]=13941

a[6]=13942

a[7]=8767 „„ „„ „„

A[252]=23583

a[253]=20265

a[254]=20266

a[255]=20267 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = The algorithm is:opt PAGE NUMBER WITH SIZE 1k FOR EACH ADDRESS IS: pageno[0]=17 pageno[1]=17

pageno[2]=17

pageno[3]=16 pageno[4]=25

pageno[5]=14

pageno[6]=14

pageno[7]=9 „„ „„ „„

pageno[252]=24

pageno[253]=20

pageno[254]=20

pageno[255]=20

vmsize=32k

pagesize=1k---------------------------page assigned

pages_in/total references 4

7.***E-1 6

7.***E-1 8

8.***E-1 10

8.***E-1 12

8.***E-1 14

9.***E-1 16

9.***E-1 18

9.***E-1 20

9.***E-1 22

9.***E-1 24

9.***E-1 26

9.***E-1 28

9.***E-1 30

9.***E-1 32

9.***E-1 PAGE NUMBER WITH SIZE 2k EACH ADDRESS IS: „„ „„ „„

PAGE NUMBER WITH SIZE 4k EACH ADDRESS IS: „„ „„ „„

PAGE NUMBER WITH SIZE 8k EACH ADDRESS IS: „„ „„ „„

End the result for opt ** ********************************************** the algorithm is lru „„ „„ „„同上

End the result for lru *********************************************(2)示例中使用的有关数据结构、常量和变量说明如下: length 被调试的指令地址流长度,可作为一个常量设定。called当前请求的页面号。

pagefault页面失效标志,如当前请求页called已在页表内,则置pagefault=false,否则为true。

table 页表。table[i]=j,表示虚存的第j页在实存的第i页中。

used当前被占用的实存页面数,可用来判断当前实存中是否有空闲页。(3)本程序启动后,屏幕上显示“the algorithm is:”,用户可选择最佳淘汰算法(打入“OPT”)或者最近最少使用淘汰算法(打入“LRU”)计算页面命中率。当然还可以加入各种其他的算法。

三、实习题

(1)编制和调试示例给出的请求页式存储管理程序,并使其投入运行。(2)增加1~2种已学过的淘汰算法,计算它们的页面访问命中率。试用各种算法的命中率加以比较分析。

提示:可选用FIFO方法,即先访问的页先淘汰,也可选用LRU方法中的其他方案。如在页表中设置标志位,按标志位值得变化来淘汰。也可用LFU方法,为页表中各页面设置访问计数器,淘汰访问频率最低的页(注意:当前访问的页不能淘汰)等等。

实验步骤与源程序 #include “iostream” #include “stdio.h” #include “stdlib.h” using namespace std;#define Max 30 //某进程调入内存中的最大页面数 #define Size 10 //系统为某进程分配的最大物理块数 void Init(int Block[],int m)//初始化物理块 { int i;for(i=0;i

Block[i]=-1;} } void creat(int Page[],int n)//输入页面串引用号 { int i;for(i=0;i

cin>>Page[i];} } void Init1(int Block1[],int m1){ int i;for(i=0;i

Block1[i]=-1;} } void creat1(int Page[],int n1){ int i;for(i=0;i

Page[i];} } void LRU(int Page[],int Block1[],int n1,int m1){ int i,j,max_stay=0,count=0;int get=-1,flag=-1,block_num=-1;int time[Size];for(i=0;i

time[i]=0;} for(i=0;i

{ if(Block1[j]==-1)

{

get=j;//物理块j即将(/等待)驻入新页面

break;

}

}

for(j=0;j

{

if(Block1[j]==Page[i])//物理块j中页面与当前期望调入内存的页面相同

{

time[j]=0;

flag=j;

break;

}

}

for(j=0;j

{

if(time[j]>max_stay)

{

max_stay=time[j];

block_num=j;//block_num标记当前序号物理块中页面驻留时间最久

}

}

if(flag==-1)//不存在相同页面

{ if(get!=-1)//物理块即将(/等待)驻入新页面

{

Block1[get]=Page[i];//存入页面

time[get]=0;//当前物理块重新计时

for(j=0;j<=get;j++)//已驻入页面的驻留时间加1

{

time[j]++;

}

get=-1;

}

else //页面调度置换,序号block_num的物理块是驻留时间最久的

{

Block1[block_num]=Page[i];

time[block_num]=0;

for(j=0;j

{

time[j]++;

}

block_num=-1;

max_stay=0;

count++;

}

}

else //待调入页面与序号flag的物理块中页面相同

{

for(j=0;j

{

time[j]++;

}

flag=-1;

}

for(j=0;j

{

cout<<“ ”<

}

cout<

} if(n1>m1)

count=count+m1;cout<<“缺页中断次数为:”<

{ time[i]=0;} for(i=0;i

{ if(Block[j]==-1)

{

get=j;

break;

}

}

for(j=0;j

{ if(Block[j]==Page[i])

{

flag=j;

break;

}

}

for(j=0;j

{

if(time[j]>max_stay)

{

max_stay=time[j];

block_num=j;

}

}

if(flag==-1)

{ if(get!=-1)

{

Block[get]=Page[i];

time[get]=0;

for(j=0;j<=get;j++)

{

time[j]++;

}

get=-1;

}

else

{

Block[block_num]=Page[i];

time[block_num]=0;

for(j=0;j

{

time[j]++;

}

block_num=-1;

max_stay=0;

count++;

}

}

else

{

for(j=0;j

{

time[j]++;

}

flag=-1;

}

for(j=0;j

{

cout<<“ ”<

}

cout<m)

count=count+m;cout<<“缺页中断次数为:”<>m;m1=m;Init(Block,m);Init1(Block1,m1);cout<<“请输入总页面数n<=30:”;cin>>n;n1=n;cout<<“n请输入页面号引用串:”;creat(Page,n);creat1(Page,n1);while(1){ menu();cin>>t;

switch(t){ case '1':LRU(Page,Block1,n1,m1);

continue;case '2':FIFO(Page,Block,n,m);

continue;case '3':exit(0);} } }

测试数据与实验结果

图1 输入要分配的物理块数、页面总数、页面序列号

图2 LRU算法的实现

图3 FIFO算法的实现

4、小结

(1)编制评测各种算法性能的模拟程序是研制系统程序,尤其是操作系统所必须的。模拟的环境愈是真实,其结果愈是可靠,也就更有利于选择合适的方案。本实习虽属简单,但可作为一个尝试。

(2)注意正整数的范围只能从0„„32767,限制程序中的虚存尺寸为32K,实际如采用更大的虚存实存,更能说明问题。

页面置换算法理解比较容易,这次根据学号要求实现的是LRU和FIFO算法的实现。

其实这两种算法的程序编写比较容易,虽然不全是自己编写的,一部分是参考的网上的例题,但是通过对每一语句的理解,自己弄懂了整个程序的执行原理。但是,在编写过程中自己还是遇到了一些问题。

最大的一个问题就是两个算法的正确实现,在程序的编写时,两个程序是分开进行编写的,分别执行起来没有什么问题,但是把两个程序融合在一起后,却出现了问题,即在执行完成一个算法后再执行另外一个算法时,开始的数据是紧接着上次算法结果的数据进行实验的。这个问题困扰了我好长时间,直到现在还没有很好的解决掉,程序只能分别执行一次,如果再进行执行的话,就会出现问题。

自己的编程技术不好,程序编的也很繁琐,但是基本的要求已经实现了,希望这次的实验是自己动手的一个开始,自己应该更加努力,再接再厉。

四、思考题

(1)设计一个界地址存储管理的模拟系统,模拟界地址方式下存储区的分配和回收过程。

提示:必须设置一个内存分配表,按照分配表中有关信息实施存储区的分配,并不断根据存储区的分配和回收修改该表。算法有首次匹配法,循环首次匹配法和最佳匹配法等。可用各种方法的比较来充实实习内容。可使用碎片收集和复盖等技术。对分区的管理法可以是下面三种算法之一: 首次适应算法 循环首次适应算法 最佳适应算法 #include #include #include #include #include #define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/ #define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/ #define minisize 100 /*空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配*/ struct { float address;/*已分配分区起始地址*/ float length;/*已分配分区长度,单位为字节*/ int flag;/*已分配区表登记栏标志,用“0”表示空栏目*/ }used_table[n];/*已分配区表*/ struct { float address;/*空闲区起始地址*/ float length;/*空闲区长度,单位为字节*/ int flag;/*空闲区表登记栏标志,用“0”表示空栏目,用“1”表示未分配*/ }free_table[m];/*空闲区表*/ void allocate(char J,float xk)/*给J作业,采用最佳分配算法分配xk大小的空间*/ { int i,k;float ad;k=-1;for(i=0;i=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length

/*修改已分配区表*/ i=0;while(used_table[i].flag!=0&&i=n)/*无表目可填写已分配分区*/ { printf(“无表目填写已分分区,错误n”);/*修正空闲区表*/ if(free_table[k].flag==0)/*前面找到的是整个空闲分区*/ free_table[k].flag=1;else {/*前面找到的是某个空闲分区的一部分*/ free_table[k].length=free_table[k].length+xk;return;} } else {/*修改已分配表*/ used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;} return;

}/*主存分配函数结束*/ void reclaim(char J)/*回收作业名为J的作业所占主存空间*/ { int i,k,j,s,t;float S,L;/*寻找已分配表中对应登记项*/ s=0;while((used_table[s].flag!=J||used_table[s].flag==0)&&s=n)/*在已分配表中找不到名字为J的作业*/ { printf(“找不到该作业n”);return;} /*修改已分配表*/ used_table[s].flag=0;/*取得归还分区的起始地址S和长度L*/ S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;/*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/ while(i=m)/*空闲区表满,回收空间失败,将已分配表复原*/ { printf(“主存空闲表没有空间,回收空间失败n”);used_table[s].flag=J;return;} free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;} return;}/*主存回收函数结束*/ int main(){ int i,a;float xk;char J;/*空闲分区表初始化:*/ free_table[0].address=10240;/*起始地址假定为10240*/ free_table[0].length=10240;/*长度假定为10240,即10k*/ free_table[0].flag=1;/*初始空闲区为一个整体空闲区*/

for(i=1;i

(2)自行设计或选用一种较为完善的内存管理方法,并加以实现。提示:设计一个段页式管理的模拟程序或通过一个实际系统的消化和分析,编制一个程序来模拟该系统。#include #include #include

struct program { char name[30];long start;long length;struct program *next;};

struct space { long start;long length;struct space *next;};

void creat();void allot();void back();void callback(program *r);void sort(space *L);void sort(program *S);void display(space *L);void display(program *S);

space *L;program *S;

void creat(){ L=new space;space *p=new space;p->start=0;p->length=128;p->next=NULL;L->next=p;S=new program;S->next=NULL;} void allot(){ program *q;q=new program;cout<<“请输入进程名和占用空间大小:”<>q->name>>q->length;if(q->length<=0){ cout<<“进程空间大小错误.”<next!=NULL&&p->next->lengthlength){ r=p;p=p->next;} if(p->next==NULL){ cout<<“占用空间过大,分配失败”<start=p->next->start;q->next=S->next;S->next=q;

p->next->length-=q->length;if(p->next->length!=0)p->next->start+=q->length;else { if(p->next->next!=NULL)p->next=p->next->next;else { r->next=NULL;delete p->next;} } } display(L);display(S);} void back(){ char name[30];cout<<“输入要回收的进程名:”;cin>>name;program *p;p=S;while(p->next!=NULL){ if(strcmp(p->next->name, name)==0){ callback(p);return;} p=p->next;} if(p->next==NULL)cout<<“此进程不存在,内存回收失败”<next;space *p,*q;long n;n=r->length;if(L->next==NULL){ space *w=new space;w->start=0;w->length=n;w->next=NULL;L->next=w;t->next=r->next;delete r;cout<<“此进程内存回收完毕.”<next;while(p!=NULL&&p->startstart){ q=p;p=p->next;} if((q->start+q->length==r->start)&&(r->start+n==p->start))//上下均空

{ q->next=p->next;q->length=q->length+p->length+n;t->next=r->next;delete r;} else if(r->start+n==p->start)//下邻空

{ p->start-=n;p->length+=n;t->next=r->next;delete r;} else if(q->start+q->length==r->start){ q->length+=n;t->next=r->next;delete r;} else { space *sp=new space;sp->start=r->start;sp->length=n;sp->next=L->next;L->next=sp;t->next=r->next;delete r;} cout<<“此进程内存回收完毕.”<next;cout<start<<“ 长度:”<

length<next;} } void display(program *S){ sort(S);program *p=S->next;cout<name<<“ 度:”<

length<next;} cout<

{ space *p=L->next, *q, *r;if(p!=NULL){ r=p->next;p->next=NULL;p=r;while(p!=NULL){ r=p->next;q=L;while(q->next!=NULL&&q->next->start

start)q=q->next;p->next=q->next;q->next=p;p=r;} } } void sort(program *S)//链表排序 { program *p=S->next, *q, *r;if(p!=NULL){ r=p->next;p->next=NULL;p=r;while(p!=NULL){ r=p->next;q=S;

起始地址:“<

start<<” 长 while(q->next!=NULL&&q->next->start

start)q=q->next;p->next=q->next;q->next=p;p=r;} } }

void main(){ creat();int a;cout<<“ 内存分配与回收模拟”<>a;if(a>2||a<0){ cout<

第二篇:操作系统课程设计文件管理

#include “stdio.h” #include “string.h” #include “malloc.h”

#include “stdlib.h”

#define MAX 1000 struct file/*普通文件的结构体*/ { //int type;//0无作用,当做一个空节点存在;1为记录型文件;2为执行文件

//前两个变量为文件的权限设置,1为允许操作,0为不允许操作

int write;//可写

int read;//可读

int length;//文件的长度

char ch[MAX];};typedef struct file File;

typedef struct ffile/*定义文件类型的结构体*/ { int type;//1为文件夹; 2为文件;

char name[20];//文件(夹)名字

int open;//文件打开标志,0为关,1为开

File iffile;//如果为文件时有的信息

struct ffile *parent;//指向上一级文件的指针

struct ffile *brother;//指向同级兄弟文件(夹)的指针

struct ffile *child;//指向下一级文件(夹)的指针 }Ffile;typedef Ffile *FFile;

/*typedef struct Open/*记录打开文件的结构体 { char name[20];//记录打开文件(夹)的名字

FFile* add;//记录打开文件上一级文件地址的指针 }Open;*/

//全局变量

FFile user1;//用户1 FFile user2;//用户2 FFile copyf;//记录被复制文件(夹)的上一级文件地址 //Open openf[20];//记录打开文件的队列

FFile init(void)/*初始化,创建根结点*/ { FFile c;c=(Ffile*)malloc(sizeof(Ffile));

c->type=2;c->open=0;//c->iffile.type=2;c->iffile.write=1;c->iffile.read=1;c->iffile.length=0;strcpy(c->name,“file1”);c->parent=NULL;c->child=NULL;c->brother=NULL;strcpy(c->iffile.ch,“NULL”);return(c);}

/*void initopen(){ int a,b;a=20;for(b=1;b<=a;b++){

openf[b].add=NULL;} }*/

//传递要显示文件的parent的地址

void show(FFile user)/*显示当前界面存在的文件*/ { user=user->child;if(user==NULL){

printf(“该文件内没有任何文件(夹)。n”);return;} printf(“n”);for(;user!=NULL;){ printf(“<%s”,user->name);if(user->type==2){

/*if(user->iffile.type==1)

printf(“/记录型文件/”);

else

printf(“/执行文件/”);*/

printf(“/%dk”,user->iffile.length);} else {

printf(“/文件夹”);

}

printf(“>n”);

user=user->brother;} }

void creatf(FFile user)/*创建文件 || 文件夹*/ { FFile parent;char ch[20];//FFile user0;//parent=(Ffile*)malloc(sizeof(Ffile));parent=user;printf(“输入要创建文件(夹)的名字:n”);

scanf(“%s”,ch);if(user->child==NULL){

user->child=(Ffile*)malloc(sizeof(Ffile));

user=user->child;}else {

user=user->child;

for(;;)

{

if(user->type==0)//开端的空结点,用新结点覆盖

break;

if(!strcmp(user->name,ch))

{

printf(“错误:该文件名已经存在,文件(夹)创建失败!n”);

return;

}

if(user->brother==NULL)

{

user->brother=(Ffile*)malloc(sizeof(Ffile));

user=user->brother;

break;

}

user=user->brother;

}

} }

//设置新文件(夹)的信息 strcpy(user->name,ch);printf(“选择创建对象:1文件夹; 2文件;n”);scanf(“%d”,&user->type);user->open=0;if(user->type==2)//添加文件信息 {

//printf(“选择文件类型:1记录型文件;2执行文件;n”);//scanf(“%d”,&user->iffile.type);printf(“能否对文件进行读:0禁止;1允许;n”);scanf(“%d”,&user->iffile.read);printf(“能否对文件进行写:0禁止;1允许;n”);scanf(“%d”,&user->iffile.write);//printf(“设置文件大小(单位:K):n”);//scanf(“%d”,&user->iffile.length);user->iffile.length=0;strcpy(user->iffile.ch,“NULL”);} user->brother=NULL;user->child=NULL;user->parent=parent;printf(“文件创建成功!n”);void deletechildtree(FFile user)/*删除子树--结合deletefile();使用*/ { if(user->brother!=NULL)//从下到上,从右到左删除

{

deletechildtree(user->brother);} if(user->child!=NULL){

deletechildtree(user->child);} if(user!=NULL){

free(user);} }

void deletefile(FFile user,char ch[20])/*删除文件 || 文件夹*/ { FFile p,parent;

int a;parent=user;if(user->child==NULL){ printf(“错误:删除失败,该目录下没有可删除的文件(夹)!n”);return;} user=user->child;p=user;for(a=1;;a++)//找出要删除文件的所在位置 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:删除失败,当前位置没有该文件!n”);

return;}

if(a>1)

p=user;user=user->brother;} if(user->open==1)//判断文件的开关情况 {

} printf(“错误:删除失败,选择文件处于打开状态!n”);return;if(p==user)//被删文件在文件队列的开头 { if(user->brother==NULL)//该文件队列只有有一个文件

{

parent->child=NULL;

if(user->child!=NULL)//删除的是文件(夹)子树

{

deletechildtree(user);}else {

free(user);//删除的是文件(夹)结点

} printf(“删除成功!n”);return;} //文件队列有多个文件 p=user->brother;

} parent->child=p;p->parent=parent;if(user->child!=NULL){ deletechildtree(user);}else { free(user);} printf(“删除成功!n”);return;else//被删文件不在队列开头 {

if(user->brother==NULL)//被删文件在文件队列最末尾 { p->brother=NULL;if(user->child!=NULL){

deletechildtree(user);}else {

free(user);}

} printf(“删除成功!n”);return;

//被删文件在文件队列中间

p->brother=user->brother;

if(user->child!=NULL)

{

deletechildtree(user);

}

else

{

free(user);

} } printf(“删除成功!n”);}

FFile openfolder(FFile user)/*打开文件夹*/ {

} //int a,b;//a=0;/*if(user->child==NULL){ user->child=(Ffile*)malloc(sizeof(Ffile));user->child->type=0;user->child->brother=NULL;user->child->parent=user;user->child->child=NULL;

} /*for(b=1;b<=20;b++){ if(openf[b].add!=NULL)

a++;} if(a==20){ printf(“错误:打开列表溢出!”);return(user);} for(b=1;;b++){ if(openf[b].add==NULL)

break;}*/

user->open=1;//设置文件为打开 //strcpy(openf[b].name,user->name);//openf[b].add=user;printf(“文件夹打开成功。n”);return(user);//返回被打开的文件夹的地址

void openfile(FFile user)/*打开普通文件*/ { if(user->open==1){

printf(“错误:打开失败,此文件已经被打开!n”);

return;} user->open=1;printf(“普通文件打开成功!n”);}

FFile openff(FFile user)/*打开文件(夹)*/ {

char ch[20];FFile parent;

int a;printf(“选择要打开的文件名:n”);scanf(“%s”,ch);

parent=user;if(user->child==NULL){

printf(“错误:打开失败,该目录下没有可打开的文件(夹)!n”);return(parent);} user=user->child;for(a=1;;a++)//找出要打开文件的所在位置 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:打开失败,当前位置没有该文件!n”);

return(parent);}

user=user->brother;} if(user->type==1){

printf(“开始打开文件夹。。n”);user=openfolder(user);} else if(user->type==2){

printf(“开始打开普通文件。。n”);

openfile(user);

user=user->parent;} return(user);}

void closefile(FFile user)/*关闭普通文件*/ {

char ch[20];int a;printf(“选择要打开的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“错误:关闭失败,该目录下没有可关闭的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要关闭文件的所在位置 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:关闭失败,当前位置没有该文件!n”);

return;}

user=user->brother;} if(user->open==0){

printf(“错误:关闭失败,该文件已经是关闭状态!n”);

return;} user->open=0;printf(“文件已经成功关闭!”);} /*没有文件夹关闭原因:

文件夹一打开就会跳向打开的新文件里 而文件夹关闭就会直接返回上一级的目录,若想整个文件夹都关闭,直接退出就可以了 因此不会直接关闭某个特定的文件*/

FFile backf(FFile user)/*返回上一层目录*/ { if(user->parent==NULL){

printf(“错误:返回失败,此处是最顶层目录!n”);

return(user);}

} user->open=0;user=user->parent;return(user);void readfile(FFile user)/*读文件*/ { char ch[20];int a;

printf(“选择要读取的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“错误:读取失败,该目录下没有可读取的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要读取文件的所在位置 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:读取失败,当前位置没有该文件!n”);

return;}

user=user->brother;} if(user->open==0){ printf(“错误:文件读取失败,该文件处于关闭状态!n”);return;} else if(user->iffile.read==0){ printf(“错误:文件读取失败,该文件受保护,禁止读取!n”);return;} printf(“读操作,该文件中的内容:n”);if(!strcmp(user->iffile.ch,“NULL”)){ printf(“该文件内没有可读内容!n”);return;

} } printf(“%sn”,user->iffile.ch);printf(“文件读取成功!n”);void writefile(FFile user)/*写文件*/ { char ch[20];int a;

} printf(“选择要进行写操作的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“错误:写操作失败,该目录下没有可写的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要读取文件的所在位置 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:写操作失败,当前位置没有该文件!n”);

return;}

user=user->brother;} if(user->open==0){ printf(“错误:文件写操作失败,该文件处于关闭状态!n”);return;} else if(user->iffile.write==0){ printf(“错误:文件写操作失败,该文件受保护,禁止写!n”);return;} printf(“写操作,输入内容:n”);scanf(“%s”,user->iffile.ch);user->iffile.length=strlen(user->iffile.ch);printf(“文件进行写操作成功!n”);

FFile copyfile(FFile user,FFile copyf)/*拷贝文件*/ { char ch[20];int a;printf(“选择要进行拷贝的文件(夹)名:n”);scanf(“%s”,ch);

if(user->child==NULL){

printf(“错误:拷贝失败,该目录下没有可拷贝的文件!n”);

return(NULL);} user=user->child;for(a=1;;a++)//找出要拷贝文件的所在位置,用user替代

{

if(!strcmp(user->name,ch))

break;

if(user->brother==NULL)

{

printf(“错误:拷贝失败,当前位置没有该文件!n”);

return(NULL);

}

user=user->brother;} copyf=user;

} printf(“拷贝成功!n”);return(copyf);FFile fenpei(FFile copyf,FFile user,FFile parent)/*粘贴时,给已拷贝项分配内存空间,以及给对应信息赋值*/ { user=(Ffile*)malloc(sizeof(Ffile));

//parent对child的连接,以及brother之间的连接已经完成if(copyf->brother==NULL && copyf->child==NULL){

user->parent=parent;

user->child=NULL;

user->brother=NULL;}

else{ if(copyf->brother!=NULL){

user->brother=fenpei(copyf->brother,user->brother,parent);//brother连接,兄弟节点有同一个父结点

user->brother->parent=user->parent;} else { user->brother=NULL;} if(copyf->child!=NULL){ //parent=p;user->child=fenpei(copyf->child,user->child,user);

user->child->parent=user;//完成child对parent的连接

//child连接,自己孩子的父结点就是自己

} else {

user->child=NULL;

user->child->parent=user;} }

//设置结点对应的信息

strcpy(user->name,copyf->name);user->open=copyf->open;user->type=copyf->type;if(user->type==2){

user->iffile.length=copyf->iffile.length;

user->iffile.read=copyf->iffile.read;

//user->iffile.type=copyf->iffile.type;

user->iffile.write=copyf->iffile.write;

strcpy(user->iffile.ch,copyf->iffile.ch);}

return(user);}

void prastefile(FFile user,FFile copyf)/*粘贴文件*/ //user是要粘贴的地方,copyf是要粘贴的内容,//有相同文件名的会判断会不会覆盖,或者是重命名 //在原树中进行新建操作 { int i,j;char ch[20];FFile p,user0,parent;parent=user;//记录父结点

user=user->child;

p=user;//记录当前结点的前一个brother结点 strcpy(ch,“NULL”);if(copyf==NULL)//判断有没有拷贝文件 {

printf(“错误:粘贴失败,还没有拷贝任何文件(夹)!n”);

return;}

//p=(Ffile*)malloc(sizeof(Ffile));//p->child=(Ffile*)malloc(sizeof(Ffile));//先给粘贴项分配内存空间

//p->child=fenpei(copyf,p->child,p);

if(user==NULL)//当前位置没有任何文件结点

{

} user=fenpei(copyf,user,parent);//是他自己要分配,不是孩子结点!!parent->child=user;user->brother=NULL;user->parent=parent;return;//该位置没有任何文件 for(j=1;;j++){ if(user->type==0)//开端的空结点,用新结点覆盖,即:当前位置没有文件结点

{

user=user->parent;

deletechildtree(p);

user=fenpei(copyf,user->child,user);//返还增加的结点

user->brother=NULL;

user->parent=parent;

parent->child=user;

} return;if(!strcmp(user->name,copyf->name)){

printf(“提示:该文件名已经存在!n”);

printf(“请重命名文件:n”);

printf(“输入新文件名:n”);

scanf(“%s”,ch);

} if(user->brother==NULL)//普通的退出条件

{

break;} p=user;user=user->brother;} user->brother=fenpei(copyf,user->brother,user->parent);user->brother->parent=user->parent;//若要更名,粘贴分配完内存空间返回时再改变

if(strcmp(ch,“NULL”))

strcpy(user->brother->name,ch);printf(“粘贴成功。n”);}

void showroute(FFile user)/*显示当前路径*/ { if(user->parent!=NULL){

showroute(user->parent);} printf(“%s/”,user->name);//路径中每个结点的输出项 }

void change(FFile user){ char ch[20];int a,b;

if(user->child==NULL)

{

} printf(“错误:属性修改失败,该目录下没有可修改的文件!n”);return;printf(“选择要进行属性修改的文件(夹)名:n”);scanf(“%s”,ch);user=user->child;for(a=1;;a++)//找出要拷贝文件的所在位置,用user替代 { if(!strcmp(user->name,ch))

break;if(user->brother==NULL){

printf(“错误:属性修改失败,当前位置没有该文件!n”);

return;}

user=user->brother;} if(user->type==1){ printf(“错误:文件夹不能进行属性修改!n”);return;} for(;;){

printf(“1.修改读权限;n”);printf(“2.修改写权限;n”);printf(“3.返回;n”);printf(“选择操作:n”);scanf(“%d”,&a);if(a==1){ printf(“0.禁止;

1.允许;n”);printf(“请选择:n”);scanf(“%d”,&b);user->iffile.read=b;printf(“修改成功!n”);} else if(a==2){ printf(“0.禁止;

1.允许;n”);printf(“请选择:n”);scanf(“%d”,&b);user->iffile.write=b;

}

} printf(“修改成功!n”);} else if(a==3){ return;} else { } printf(“错误:没有该操作!n”);void main()/*主函数*/ {

FFile d,e,f;//f记录当前显示界面父结点位置 int a,b,c;char ch[20];a=0;printf(“******************************目录******************************n”);printf(“

1.选择用户n”);printf(“

2.退出n”);

printf(“****************************************************************n”);for(;;){

printf(“选择操作:n”);scanf(“%d”,&a);if(a==1){ printf(“选择用户:n”);printf(“1.user1;n2.user2;n”);scanf(“%d”,&b);break;} else if(a==2){ printf(“欢迎使用。n”);exit(0);//系统退出的操作码 } else { printf(“错误:没有该操作!n”);

} } //初始化打开列表 //initopen();//初始化各个用户的信息

//copyf=(Ffile*)malloc(sizeof(Ffile));//copyf=NULL;copyf=NULL;user1=init();strcpy(user1->name,“user1”);user2=init();strcpy(user2->name,“user2”);d=init();e=init();user1->child=d;user2->child=e;d->parent=user1;e->parent=user2;printf(“%d”,user1->child->type);if(b==1){ printf(“已经进入user1系统n”);f=user1;show(user1);}else{

} printf(“已经进入user2系统n”);f=user2;show(user2);

for(;;){ printf(“****************************************************************n”);printf(“1.创建文件(夹)

5.读文件

9.显示当前路径

n”);printf(“2.删除文件(夹)

6.写文件

10.返回上一层目录

n”);printf(“3.打开文件(夹)

7.拷贝文件

11.改变普通文件属性n”);printf(“4.关闭普通文件

8.粘贴文件

12.退出n”);printf(“****************************************************************n”);printf(“选择操作:n”);scanf(“%d”,&c);if(c==12){

break;}else if(c==1){ creatf(f);} else if(c==2){

printf(“选择要删除的文件(夹)的名字:n”);scanf(“%s”,ch);deletefile(f,ch);} else if(c==3){ f=openff(f);} else if(c==4){ closefile(f);} else if(c==5){ readfile(f);} else if(c==6){ writefile(f);} else if(c==7){ copyf=copyfile(f,copyf);} else if(c==8){ prastefile(f,copyf);copyf=NULL;} else if(c==9){ printf(“路径为:n”);showroute(f);printf(“n”);} else if(c==10){

}

f=backf(f);

} else if(c==11){ change(f);} else { continue;} show(f);} printf(“欢迎使用!n”);

第三篇:操作系统课程设计_动态分区分配存储管理

操作系统课程设计

设计题目 动态分区分配存储管理

学生姓名学

号 专业班级 指导教师

吕 霆

20102675 计算机10-01班

第一章

课程设计概述

1.1 设计任务: 动态分区分配存储管理

1.2 设计要求

建立描述内存分配状况的数据结构; 建立描述进程的数据结构; 使用两种方式产生进程:(a)自动产生,(b)手工输入;  在屏幕上显示内存的分配状况、每个进程的执行情况;  建立分区的分配与回收算法,支持紧凑算法;  时间的流逝可用下面几种方法模拟:(a)按键盘,每按一次可认为过一个时间单位;(b)响应WM_TIMER;

 将一批进程的执行情况存入磁盘文件,以后可以读出并重放;

 支持算法:首次适应算法、循环首次适应算法、最佳适应算法:最坏适应算法。

1.3 设计目的

旨在让我们更好的了解动态分区管理方面的知识.第二章 原理及算法描述

2.1动态分区分配算法原理

首次适应算法

* 算法概述:分配内存时,从链首开始顺序查找,找到满足的空闲分区则划出空间分配,余下的空闲空间仍保留在空闲链表中

* 实现方法:分配时从数组第一个元素开始比较,若符合条件则将该元素减去对应作业的值

循环首次适应算法

* 算法概述:由首次适应算法演变,只是每次分配改为由上一次找到的空闲分区开始查找

* 实现方法:在首次适应算法的基础上增加一个值用于记录找到的空闲分区的位置

最佳适应算法

* 算法概述:每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区

分配给作业

* 实现方法:我们决定每次分配先把空闲分区按从小到大的顺序排列,然后将第一个匹配分区分配给作业

最坏适应算法

* 算法概述:每次为作业分配内存时,总是挑选一个最大的空闲分区分割给作业使用

* 实现方法:算法与最佳适应算法几乎相同,仅在排序时把空闲分区表按从大到小的顺序排列,所以未作详细注释

回收分区

当进程运行完毕释放内存时,系统根据回收区的首址,从空闲区链(表)中找到相应的插入点,此时可能出现以下四种情况之一;1)回收区与插入点的前一个空闲分区F1相邻接,此时应将回收区与插入点的前一分区合并,不必为回收区分配新表项,而只需修改其前一分区F1的大小.2)回收分区与插入点的后一空闲分区F2相邻接,此时也可将两分区合并,形成新的空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和.3)回收区同时与插入点的前,后两个分区邻接,此时将三个分区合并,使用F1的表项和F1的首址,取消F2的表项,大小为三者之和.4)回收区既不与F1相邻接,又不与F2邻接.这时应为回收区单独建立一新表项,填写回收区的首址和大小,并根据其首址插入到空闲链中的适当位置.紧凑算法

通过移动内存中的作业的位置,以把原来多个分散的小分区拼接成一个大分区的方法.第三章 开发环境

此程序是本人利用c++语言在vs2012的开发环境中实现的第四章 程序实现--数据结构

#include #include #include using namespace std;ofstream stream;//输出流对象 int ary1[20][4];//内存分配状态 int ary2[20][3];//空闲分区状态 int ary3[10];//进程分配状态

int recycle;//需要回收的盘块序号 int id1;//算法选择号 int m;//内存区数 int n;//空闲区数 int q;//进程数

int r=0;//循环首次适应算法:对应的这次查找到的空闲分区序号 //打印输出函数 void vision(){

int i;int j;if(id1==1)stream.open(“first_fit.txt”, ios::app);if(id1==2)stream.open(“nextfirst_fit.txt”, ios::app);if(id1==3)stream.open(“best_fit.txt”,ios::app);if(id1==4)stream.open(“worst_fit.txt”, ios::app);if(id1==5)stream.open(“compact.txt”,ios::app);if(id1==6)stream.open(“huishou.txt”,ios::app);cout<<“-------------内存分配状态-------------”<

} cout <

} cout <

}

//作业信息的自动产生 void create_pro(){

}

//作业的手动生成 void create_zuoye(){ int j;int choice2;int id3=rand()%10;m=id3;//内存区数量 cout<<“产生”<

} ary3[0]=42;ary3[1]=86;ary3[i]=rand()%100;if(ary3[i]==0){i--;} {

} cout<<“--------------------------”<

}

//内存信息的自动产生 void create_apply(){

int k=0;//空闲区数量 for(i=0;i

if(ary1[i][3]!=2){ary2[k][0]=ary1[i][0];ary2[k][1]=ary1[i][1];ary2[k][2]=ary1[i][2];k++;} int i;for(i=0;i

} ary1[i][0]=i+1;ary1[i][1]=rand()%100;if(i==0){ } ary1[i][3]=rand()%3;//cout <>choice2;q=choice2;cout<<“输入想创建的作业请求大小”<

} cout<<“你创建了”<>j;ary3[i]=j;

}

//内存信息的手动生成 int create_fenqu(){

}

//首次适应算法 void first_fit()int k,x,y,o=0;int a=0;cout<<“输入想创建的内存分区块数 : ”;cin>>k;

cout<<“输入”<

} cout<<“输入内存块的分配状态”<

} ary1[0][2]=0;ary1[1][2]=ary1[0][1];for(int i=2;i

for(int i=0;i

} n=a;return m,n;if(ary1[i][3]!=2){

} ary2[a][0]=ary1[i][0];ary2[a][1]=ary1[i][1];ary2[a][2]=ary1[i][2];a++;ary1[i][2]=ary1[i-1][2]+ary1[i-1][1];//起始地址 cin>>y;if(y==2){ } ary1[i][3]=y;//状态 n++;ary1[i][0]=i;//序号 cin>>x;ary1[i][1]=x;//大小 } n=k;//空闲块数量

{

vision();int i;int j;int k;int l;int d;//用来保存第k个的值 int id2=0;for(i=0;i

for(j=0;j

if(ary2[j][1]>=ary3[i])//进程占用空间小于等于其中一个空闲区的大小 {

cout<<“[”<

ary1[ary2[j][0]-1][3]=2;for(k=j+1;k

ary2[k-1][0]=ary2[k][0];ary2[k-1][1]=ary2[k][1];ary2[k-1][2]=ary2[k][2];} n--;

}else//否则的话,空闲链对应的地方盘块大小小了进程占用的大小,并且内存分配从对应的 {

l=ary2[j][0];d=ary1[l-1][1];//大小 ary1[l-1][1]=ary3[i];ary1[l-1][3]=2;m++;for(k=m;k>ary2[j][0]+1;k--){

ary1[k-1][0]=ary1[k-2][0]+1;ary1[k-1][1]=ary1[k-2][1];ary1[k-1][2]=ary1[k-2][2];ary1[k-1][3]=ary1[k-2][3];那一项开始增加一项

} l=ary2[j][0];

}

}

{ if(ary1[id2][3]!=2)

}

} n=k;} break;} else {

}

cout<<“[”<

{

ary2[k][0]=ary1[id2][0];ary2[k][1]=ary1[id2][1];ary2[k][2]=ary1[id2][2];k++;} ary1[l][0]=l+1;ary1[l][1]=d-ary3[i];ary1[l][2]=ary1[l-1][1]+ary1[l-1][2];ary1[l][3]=0;k=0;for(id2=0;id2

//首次循环适应算法 void next_fit(){ vision();int i;int j;int k;int s;int d;int id2;for(i=0;i

{

for(j=r;j

if(ary3[i]<=ary2[j][1]){

cout<<“[”<

{

} else//对应的空闲块大小大于进程需要大小 { //-----改变内存分配情况-----r=(r+1)%n;//改变第k块的内容 k=ary2[j][0];d=ary1[k-1][1];ary1[k-1][1]=ary3[i];ary1[k-1][3]=2;//从k+1之后所有向后移一格 m++;//内存块数增加1 for(s=m-1;s>k;s--){

ary1[s][0]=ary1[s-1][0]+1;ary1[s][1]=ary1[s-1][1];ary1[s][2]=ary1[s-1][2];//---改变内存分配---k=ary2[j][0];//得到对应空闲块对应内存块的序号 k--;ary1[k][3]=2;//把对应内存块标志位上改成已分配 //------------------//--改变空闲块表:把从这块空闲块以下的所有空闲块向上移一格--n--;for(k=j;k

} vision();//------------------break;ary2[k][0]=ary2[k+1][0];ary2[k][1]=ary2[k+1][1];ary2[k][2]=ary2[k+1][2];stream<<“[”<

}

}

//思路:先把空闲列表检索一遍,选出最佳答案,进行分配

void best_fit()//最佳算法--按顺序检索,把与进程要求内存大小最接近的快分配给进程 {

int i;int s;int j=-9999;//用来保存最接近的答案 int e;//用来存放进行比较时的中间结果

}

{ if(ary1[id2][3]!=2)

}

} else{

} cout<<“[”<

{

ary2[k][0]=ary1[id2][0];ary2[k][1]=ary1[id2][1];ary2[k][2]=ary1[id2][2];k++;} ary1[s][3]=ary1[s-1][3];} //改变第k+1块内容:对应的数组是ary1[k] ary1[k][0]=ary1[k-1][0]+1;ary1[k][1]=d-ary1[k-1][1];ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];//--------------------------//----改变空闲表分配情况----k=0;for(id2=0;id2

}else { cout<<“[”<

for(s=0;s

} if(j<0){ cout<<“[”<=ary3[i])&&(e>ary2[s][1]))//满足分配要求 { e=ary2[s][1];} j=s;for(i=0;i

if(ary2[j][1]==ary3[i]){

} else

for(l=k;l

} n--;ary2[l-1][0]=ary2[l][0];ary2[l-1][1]=ary2[l][1];ary2[l-1][2]=ary2[l][2];ary1[k-1][3]=2;k=ary2[j][0];

}

//最坏适应算法 void worst_fit()

}

{ if(ary1[id2][3]!=2)

}

} vision();n=k;

} for(k=j+1;k

{

ary2[k][0]=ary1[id2][0];ary2[k][1]=ary1[id2][1];ary2[k][2]=ary1[id2][2];k++;} {

//把对应的内存分配进行更改 k=ary2[j][0];d=ary1[k-1][1];ary1[k-1][1]=ary3[i];ary1[k-1][3]=2;m++;for(l=m;l>ary2[j][0]+1;l--){

} k=ary2[j][0];ary1[k][0]=k+1;ary1[k][1]=d-ary1[k-1][1];ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];ary1[k][3]=0;k=0;ary1[l-1][0]=ary1[l-2][0]+1;ary1[l-1][1]=ary1[l-2][1];ary1[l-1][2]=ary1[l-2][2];ary1[l-1][3]=ary1[l-2][3];for(id2=0;id2

{

}else { cout<<“[”<

int e=-9999;//用来存放进行比较时的中间结果 int k;int l;int d;int id2;vision();{

j=-9999;e=-9999;for(s=0;s

} if(j<0){ cout<<“[”<=ary3[i])&&(e

if(ary2[j][1]==ary3[i]){

k=ary2[j][0];

ary1[k-1][3]=2;

for(l=k;l

{ if(ary1[id2][3]!=2)

}

} vision();n=k;

} for(k=j+1;k

{

ary2[k][0]=ary1[id2][0];ary2[k][1]=ary1[id2][1];ary2[k][2]=ary1[id2][2];k++;}

} else {

//把对应的内存分配进行更改 k=ary2[j][0];d=ary1[k-1][1];ary1[k-1][1]=ary3[i];ary1[k-1][3]=2;m++;for(l=m;l>ary2[j][0]+1;l--){

}

k=ary2[j][0];ary1[k][0]=k+1;ary1[k][1]=d-ary1[k-1][1];ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];ary1[k][3]=0;k=0;ary1[l-1][0]=ary1[l-2][0]+1;ary1[l-1][1]=ary1[l-2][1];ary1[l-1][2]=ary1[l-2][2];ary1[l-1][3]=ary1[l-2][3];} n--;ary2[l-1][2]=ary2[l][2];for(id2=0;id2

}

//回收内存算法: /* 有共计八种情况,1.(1)回收区上邻接着空闲盘块,下连接着已分配盘块(2)回收区下邻接着空闲盘块,上邻接着已分配盘块(3)回收区上下连接的都是空闲盘块(4)空闲区上下邻接的都是已分配盘块

(5)要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块(6)要回收的盘块就是第一个盘块,但是向下邻接着已分配盘块(7)要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块(8)要回收的盘块就是最后一个盘块,但是向上邻接的是已分配盘块 */ void apply_recycle(){

ary1[0][1]=ary1[0][1]+ary1[1][1];ary1[0][3]=0;for(i=1;i

if(recycle==1){ //cout<

if(ary1[1][3]!=2){ cout<<“要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块”<

} else { ary1[0][3]=0;n++;ary2[0][0]=1;ary2[0][1]=ary1[0][1];ary2[0][2]=ary1[0][2];vision();} stream<<“要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块”<

ary2[k][0]=ary1[j][0];

ary1[0][3]=0;k=0;for(j=0;j

//cout<<“ary1[j][3]”<

} else{ cout<<“要回收的盘块就是第一个盘块,但是向下邻接着已分配盘块”<

} n=k;vision();

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;

{

} m--;// cout<<“" k=0;vision();//cout<<”ary1[0][3]“<

cout<<”ary1[j][3]“<

} else{ cout<<”要回收的盘块就是最后一个盘块,但是向上邻接的是已分配盘块“<

} n=k;vision();

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;

ary1[recycle-2][3]=0;ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];m--;k=0;for(j=0;j

//cout<<”ary1[j][3]“<

} else if(recycle==m){

if(ary1[recycle-2][3]!=2){ cout<<”要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块“<

} n=k;vision();

}

ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;stream<<”要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块“<

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;

} else{//剩下比较复杂的四种情况

if((ary1[recycle-2][3]!=2)&&(ary1[recycle][3]==2))//回收区上邻接着空闲盘块,下连接着{cout<<”回收区上邻接着空闲盘块,下连接着已分配盘块“<

}

} n=k;vision();

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;

ary1[recycle-1][3]=0;k=0;for(j=0;j

//cout<<”ary1[j][3]“<

stream<<”回收区上邻接着空闲盘块,下连接着已分配盘块“<

ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];for(i=recycle-1;i

} m--;k=0;for(j=0;j

//cout<<”ary1[j][3]“<

} if((ary1[recycle-2][3]!=2)&&(ary1[recycle][3]!=2))//回收区上下连接的都是空闲盘块 { cout<<”回收区上下连接的都是空闲盘块“<

} vision();

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;

} n=k;vision();} if((ary1[recycle][3]!=2)&&(ary1[recycle-2][3]==2))//回收区下邻接着空闲盘块,上邻接着{ cout<<”回收区下邻接着空闲盘块,上邻接着已分配盘块“<

stream<<”回收区下邻接着空闲盘块,上邻接着已分配盘块“<

ary1[recycle-2][3]=0;ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];for(i=recycle-1;i

} m--;k=0;for(j=0;j

//cout<<”ary1[j][3]“<

}

}

} if((ary1[recycle-2][3]==2)&&(ary1[recycle][3]==2))//空闲区上下邻接的都是已分配盘块 {

} ary1[recycle-1][3]=0;k=0;for(j=0;j

} vision();//cout<<”ary1[j][3]“<

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;cout<<”回收区上下连接的都是空闲盘块“<

} m=m-2;k=0;for(j=0;j

} vision();//cout<<”ary1[j][3]“<

}

ary2[k][0]=ary1[j][0];ary2[k][1]=ary1[j][1];ary2[k][2]=ary1[j][2];k++;ary1[recycle-1][0]=ary1[recycle+1][0]-2;ary1[recycle-1][1]=ary1[recycle+1][1];ary1[recycle-1][2]=ary1[recycle+1][2];ary1[recycle-1][3]=ary1[recycle+1][3];n=k;n=k;

}

//紧凑算法 void compact(){

num_avl=0;for(id2=0;id2

int num_avl;//记录空闲盘块数量 int sum_avl=0;//总共空闲区大小 int num_apl=0;//统计总共空闲区有多大 vision();for(id2=0;id2

} //最后一块空闲块

ary1[num_apl][0]=num_apl+1;ary1[num_apl][1]=sum_avl;ary1[num_apl][2]=ary1[num_apl-1][1]+ary1[num_apl-1][2];ary1[num_apl][3]=0;m=num_apl+1;//包括最后一个空闲区 if(ary1[id2][3]==2){

} ary1[num_apl][0]=num_apl+1;ary1[num_apl][1]=ary1[id2][1];if(num_apl==0){

} ary1[num_apl][3]=2;num_apl++;//cout<<”num_apl“<

}

//主函数入口

void main(){

if(choice1==1){

}

num=rand()&10;q=num;int id3=2+rand()%8;m=id3;//内存区数量 create_apply();create_pro();int i;int j;int num;int choice1;//操作选择标记 int choice2;int flag=1;//标记是否再执行 while(flag==1){

cout<<”********************************************“<>choice1;

} n=num_avl;vision();

} ary2[num_avl][0]=ary1[id2][0];ary2[num_avl][1]=ary1[id2][1];ary2[num_avl][2]=ary1[id2][2];num_avl++;if(choice1==2){

} vision();

cout<<”**------------------请选择处理算法----------------------**“<

} }

cout<<”**************************** “<>o;flag=o;

cout<<”**1首次适应算法-----2循环首次适应算法-----3最佳适应算法 **“<>id1;if(id1==1)if(id1==2)if(id1==3)if(id1==4)if(id1==5)

} {first_fit();} {next_fit();} {best_fit();} {worst_fit();} { compact();} if(id1==6){ cout<<”*******************生成内存状态******************“<>recycle;if((recycle>m)||(recycle<1)){

} cout<<”错误:内存中不存在此块!“<

} if(id2==-9999){ apply_recycle();} if(ary2[i][0]==recycle){

}

cout<<”错误:输入的为空闲盘块!"<

第四篇:操作系统课程设计++模拟磁盘文件管理的程序

中南林业科技大学

操作系统课程设计

课程题目:模拟磁盘文件管理的程序

姓名: 学号:

专业: 计算机科学与技术 年级:

2006

计算机科学学院

2008年11月 模拟磁盘文件管理的程序

一、课程设计内容

⑴ 自定义磁盘文件管理的数据结构; ⑵ 能够自由创建、修改、删除文件; ⑶ 文件具有一定自定义的属性; ⑷ 能够显示当前系统文件的状态。

二、课程设计的数据结构说明

程序中定义了两个类: class file//文件类 {private: char name[10];//文件名 public: int tag;//删除标记 1:已删 0:未删 file(){ } char *getname(){return name;} //获取文件名

int gettag(){return tag;} //获取删除标记

int getlength(){return length;} //获取文件大小

int getblocknum(){return blocknum;} // 磁盘块数

int getblocksum1(){return blocksum1;} //磁盘块号的始点 int getblocksum2(){return blocksum2;} //磁盘块号的终点 int length,blocknum,blocksum1,blocksum2;

void setname(char na[ ]){strcpy(name,na);} //设置文件名 void delwenjian(){ tag=1;}//设置删除标记 1:已删 0:未删

void creatfile(char *na,int L,int num,int s1,int s2)//创建文件 void deltefile(char *na){tag=1;strcpy(name,na);} //删除文件 void disp()//输出文件信息 class fdatabase //文件库类 { private: int top;//文件记录指针 file f[50];public: fdatabase(){top=-1;} //构造函数 int search(char *fname)//按文件名查找

int creatfile(char *na,int L,int num,int s1,int s2)//创建文件时先查找是否存在

int deltefile(char *na)//删除文件时先查找是否存在 void disp()//输出所有文件信息 };

三、课程设计的模板说明

1、初始化,建立文件系统

输入磁盘大小(G),每个盘块大小(M),自动建立位示图,位示图字长定为32位

输出位示图的行数,以及行号、列号与磁盘块号的转换公式(都从0开始编号)。

2、循环选择执行以下功能

1、存储文件

输入建立的文件名和文件大小,如果该文件名已经存在,则输出不能建立的信息否则计算所需的磁盘块数

为其分配足够多的磁盘块,并记录下来 输出所占用的磁盘块号

2、删除文件

输入要删除的文件名,如果该文件名不存在,则输出删除错误信息,否则收回该文件所占用的磁盘块 删除该文件名

3、显示位示图情况

显示位示图的情况 显示剩余磁盘块的数目

4、显示文件列表

显示文件名,文件大小,占用的磁盘块数目和磁盘块号

四、课程设计的源代码

#include #include #include #include #include int i=0,j=0,sum=0,tt=0,r,ii,k,g,m;int a[100][32];class file//文件类 {private: int no;//文件编号

char name[10];//文件名 public: int tag;//删除标记 1:已删 0:未删 file(){ } char *getname(){return name;} //获取姓名

int gettag(){return tag;} //获取删除标记

int getno(){return no;} //获取文件编号

int getlength(){return length;} //获取文件大小

int getblocknum(){return blocknum;} // 磁盘块数 int getblocksum1()//磁盘块号的始点 { return blocksum1;} int getblocksum2()//磁盘块号的终点 { return blocksum2;} int length;//文件大小

int blocknum;//盘块数

int blocksum1;//所占盘块号的始点

int blocksum2;//所占盘块号的终点

void setname(char na[ ])//设置文件名

{strcpy(name,na);} void delwenjian(){ tag=1;}//设置删除标记 1:已删 0:未删

void creatfile(char *na,int L,int num,int s1,int s2)//创建文件 { tag=0;length=L;blocknum=num;blocksum1=s1;blocksum2=s2;strcpy(name,na);blocknum=length/m;//盘块数=文件大小/盘块大小 if(length%m!=0)//盘块数取上整 blocknum=blocknum+1;cout<<“ 所需磁盘块数:”<

for(;j<32;j++)

a[i][j]=1;i=i+1;for(j=0;j<(sum+blocknum)-32;j++)//再进行剩余项赋值

{

a[i][j]=1;} sum=sum+blocknum-32;} tt=tt+blocknum;//输出文件所占用的盘块号

cout<<“ 所占磁盘块号:”<

{

for(ii=0;ii<=top;ii++)

{ if(strcmp(f[ii].getname(),fname)==0 && f[ii].tag==0)

return 0;

}

return 1;} int creatfile(char *na,int L,int num,int s1,int s2)//创建文件时先查找是否存在

{ int p;p=search(na);

if(p==1)

{ top++;

f[top].creatfile(na,L,num,s1,s2);

return 1;}

else

{cout<<“!!该文件已存在,不能创建!!nn”;

return 0;} } int deltefile(char *na)//删除文件时先查找是否存在{int b,p,x=0,n1,n2,q1,q2,t;p=search(na);if(p==0)//若文件存在

{ //进行删除文件赋值

f[ii].tag=1;b=f[ii].length/m;//盘块数=当前文件大小/盘块大小

if(ii==0)// 对第一个删除文件进行赋值

for(k=0;k

a[x][k]=0;

else{ n1=(f[ii-1].blocksum2+1)/32;//被查找的文件之前文件所占用的盘块数

/32,//大于0表示跨行

n2=(f[ii].blocksum2+1)/32;//所有文件所占用的盘块数/32,大于0表示跨行

q1=(f[ii-1].blocksum2+1)-n1*32;// 当前文件的开始盘块号 q2=(f[ii].blocksum2+1)-n2*32;// 用于跨行后计算盘块号 t=n2-n1;if(t==0)//若n2与n1相等,表明当前所有被占用盘块在同一行

for(k=q1;k<1+b;k++)

a[n2][k]=0;

else { if((f[ii-1].blocksum2+1)%32==0)//前面所占用的盘块数是32倍数

{ x=x+n1;//当前文件赋值

for(;t-1>=0;t--,x++)//循环进行整行赋值

for(k=0;k<32;k++)

a[x][k]=0;

x=n2;//对剩余项赋值

for(k=0;k

a[x][k]=0;

} else //对当前文件前几项赋值

{ x=n1;

for(k=q1;k<32;k++)

a[x][k]=0;x=x+1;int t1=t;

for(;t-1>0;t--,x++)//中间整行赋值

for(k=0;k<32;k++)

a[x][k]=0;

x=n2;//最后剩余项赋值

for(k=0;k<(f[ii].blocksum2+1)-t1*32;k++)

a[x][k]=0;

}

} return 1;} } else

{cout<<“该文件不存在”;

return 0;}

} void disp()//输出所有文件信息 { for(int i=0;i<=top;i++)

if(f[i].tag==0)

f[i].disp();} };void bit_map(int I){ int s=0;cout<<“-”<

cout<

out<<“--”<>g;cout<>m;cout<

a[i][j]=0;

cout<<“ 建立的位示图为:”<

cout<<“ 行数:”<

cout <<“ttt1

存 储 文 件nnttt2

删 除 文 件 nnttt3 显示位示图情况 nnttt4 显示文件列表”<> choice;cout<

case '1':

cout <<“ 请输入文件名: ”;

cin>>fname;

cout<

if(q==0)

{ cout<<“!!该文件已存在,不能创建!!nn”;

break;}

cout <<“ 请输入文件大小MB: ”;

cin>>l;

cout<

if(l>g*1024)

{cout<<“!!文件大小超过磁盘最大容量,无法进行分配!!”<

break;}

p.creatfile(fname,l,b,ss1,ss2);

break;

case '2':

cout <<“ 请输入文件名: ”;

cin>>fname;

cout<

q=p.search(fname);

if(!q==0)

{

cout<<“!!该文件不存在,无法删除!!nn ”;

break;

} p.deltefile(fname);

break;case '3':

cout <<“tt**************显示位示图如下*********************n”;

bit_map(I);

cout<

break;

case '4': cout <<“tt*************文件列表如下************************n”;cout<<“-”<

p.disp();

cout<

break;default:

cout<<“输入错误,请从新输入: nn”;

break;} } }

五、课程设计程序运行结果

1、初始化,建立文件系统

(1)用户根据提示输入磁盘大小(GB)与每个盘块大小(MB);

(2)程序首先根据用户输入的磁盘大小(GB)与每个盘块大小(MB),自动建立位示图,即初始化位示图,位示图每一行长度固定为32位(即列固定为32);位示图中每一位表示一个盘块,取值0和1分别表示空闲和占用。初始化的位示图应全为0;

(3)程序再输出位示图的剩余盘块数,行数,以及行号、列号与磁盘块号的转换公式(行列皆从0开始编号);

这样,初始化,建立文件系统完成。运行结果:

2、选择执行:存储文件,删除文件,显示位示图情况,显示文件列表 【显示文件管理系统列表】显示文件系统管理列表,并提示输入信息1——4。用户输入文件操作命令1(存储文件),2(删除文件)、3(显示位示图情况)、4(显示文件列表);

格式如下:键入1,创建文件名为fname,大小为L(MB)的文件;

键入2,删除文件名为fname的文件;

键入3,显示位示图情况;

键入4,显示所有文件信息。

运行结果:

【存储文件】

用户输入文件操作命令是1(存储文件)。系统提示你输入你要建立的文件名和文件大小,如果该文件名已经存在,则系统提示输出不能建立此文件的信息,否则计算所需的磁盘块数和所占用的磁盘块号,并输出结果。相应的在位示图上,因为位示图是矩阵,可以用数组存储,根据所占用的磁盘块号和公式:

磁盘块号=行号*32+列号 行号=磁盘块号/32

列号=磁盘块号%32 计算出文件占用的磁盘块在位示图上的位置,现在是创建文件,所以将位示图该位置上的二进制数置1,表示已分配出去。

分别创建名为ll,zz和mm三个文件,文件大小分别为224MB,320MB和56MB。

此时对应的位示图如下:

文件列表如下:

若再创建一个已经创建过的文件,则显示如下信息:

若创建的文件大小超过磁盘的最大容量,则显示如下信息:

【删除文件】

用户输入文件操作命令是2(删除文件)。系统提示你输入要删除的文件名,如果该文件名不存在,则输出删除出错信息。在位示图上,根据所占用的磁盘块号和公式:

磁盘块号=行号*32+列号 行号=磁盘块号/32 列号=磁盘块号%32 计算出文件占用的磁盘块在位示图上的位置,现在是删除文件,所以将位示图该位置上的二进制数置0,表示收回该文件所占用的磁盘块。删除第二个文件zz,结果如下:

则相应的位示图和文件列表变为:

若删除一个不存在的文件,则显示如下信息:

【显示位示图情况】

如果用户输入文件操作命令是我wst()(显示位示图情况),系统输出此时位示图的情况,状态位为'0'表示对应盘块空闲,状态位为'1'表示该盘块已被分配出去。系统再显示剩余磁盘块的数目。

以下是删除zz文件,创建xx后和创建xx后,删除ll的位示图:

【显示文件列表】

如果用户输入文件操作命令是disp()(显示所有文件情况),系统会显示所有文件的文件名,文件大小,占用的盘块数和盘块号。

以下是删除zz文件,创建xx后和创建xx后,删除ll显示的文件列表:

第五篇:页式存储管理方案中的内存分配

页式存储管理方案中的内存分配

用户提出内存空间申请,按一定策略检查内存空间,找出满足请求的空闲页面,分给申请者

1首先接收输入文件:

(1)内存空闲物理页面文件(文本文件),包括若干行,每行2项(起始

物理页面号,连续的物理页面数)

(2)进程占用物理内存数据文件(文本文件),包括若干行,若干项(进

程号,物理页面号1,物理页面号2,……)建立空闲页面表,并在屏幕显示输出该表内容 20行

该表中记录了内存中可供分配的空闲页面的起始页号和连续空闲的页面数 3为每个进程建立一个页表,并在屏幕显示输出每个页表的内容

页表记录了每个进程逻辑页面与物理页面的对应关系在用户界面根据用户提示接收一个内存申请,格式为:进程名,申请空间大小(单位为K字节)为该进程建立一个页表,显示输出该表内容,检查空闲页面表,为该进程分配相应的物理页面,并修改有关的数据结构(空闲页面表,页表)假设页面大小为4K重复4,5直到输入特殊字符(0)在屏幕显示输出最新的空闲页面表内容

下载操作系统课程设计之请求式面页管理word格式文档
下载操作系统课程设计之请求式面页管理.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    数据库课程设计之教务管理系统

    源代码: CREATE DATABASE JWGL/*建立教务管理系统*/ ON (NAME = JWGL_Data, FILENAME = 'e:sql_dataJwgl_Data.mdf', SIZE = 20, MAXSIZE = 500, FILEGROWTH = 25%) LOG ON......

    软件工程课程设计之——学生成绩管理系统

    1. 设计背景 随着科学技术的不断提高,计算机科学技术日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。 现在我国的教育机构对学......