注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

我的博客

 
 
 

日志

 
 

操作系统实验报告——存储器分配  

2007-12-05 23:22:53|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

实验名称:主存储器空间的分配和回收

实验内容:主存储器空间的分配和回收。。   

实验目的:计算机系统不仅要有足够的容量、存取速度快、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。主存的分配和回收的实现是与主存储器的管理方式有关的。本实验有助于了解在不同的存储管理方式下,应怎样实现主存空间的分配和回收。

实验题目:在可变分区管理方式下,采用最先适应算法实现主存空间的分配和回收。

实验要求:(1)假设主存空间大小,预设操作系统所占大小并构造未分分区表。未分分区表目内容包括起始地址、长度、状态(未分/空表目)

            (2)结合实验一,PCB的内容增加为: PID、要求运行时间、优先权、状态、所需主存大小、主存起始位置、PCB指针。

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

            (4)进程完成后,回收主存,并与相邻空闲分区合并。

实验分析: 可变式分区管理的原理:区域的大小及起始地址是可变的,根据程序装入时的大小动态地分配一个区域。保证每个区域之中刚好放一个程序。这样可以充分地利用存储空间,提高内存的使用效率。如果一个程序运行完毕,就要释放出它所占有的分区,使之变成空闲区。这样就会出现空闲区与占用区相互交错的情况。这样就需要P表,F表来分别表示内存的占用区状态与空闲区的状态。

             确定该系统所使用的数据结构:我们可以把内存表示为一个数组的形式。这个数组中的每一个单元都是一个无符号的字符型的数据类型。这样一个单元刚好占用一个字节的大小。这一个字节的地址可以用它在此数组中的下标来表示。如果一个程序占用了一定的区域,那么这个区域的大小就可以用它占有的字节数的个数来表示。为了实现可变式的分区管理,还需要设立两个表,一个是P表,一个是F表,它们分别表示内存的占用区状态。由于在该程序运行的过程之中需要不断地修改P表和F表,所以这两个表不适合于用数组的形式来表示;而应该使用单链表的形式。这样就要给单链表中的结点确立一个数据结构。很显然,P表中的每一个结点至少要包括以下的几项:占用的程序名、占用区的起始地址、占用区的大小、指向下一个结点的指针。F表中的结点可以不需要程序名这一项。但是为了统一起见,我们就统一地采用P表中的这种结点的结构。

分区分配的主要步骤有:从未分配表中找到一个足以容纳该作业的可用空闲区;如这个空闲区比所要求的大,则将它分成两部分:一部分成为已分配的分区,剩下部分仍为空闲区;修改两张表的有关信息,并回送一个所分配分区的序号或该区的首址。(2)系统回收一个分区的主要步骤有:检查回收分区是否与空闲区邻接,如邻接则加以合并,使之成为一个连续的大空闲区。修改两张说明表。

实验心得:通过这次实验我练习了用C++语言写系统软件,对OS中可变分区存储管理有了更深刻的了解。在写程序的时候也遇到了一些困难。比如在设计数据结构时特别犹豫,总想找一个很合适的。但是,后来才知道,关键要多尝试,而空想是没有用的。最后我证实了自己的设计的合理性。还有为了使程序更健壮,我尝试着将程序中的输入部分全部改为字符(串)。成功的避免了接受整型数据时输入字符后引起的错误,使程序能接受任何输入而正常结束。很遗憾的是因为时间问题,没有把这个模拟程序写成动画形式,还可以加几句代码后实现动态的增加作业。

实验参考书:《计算机操作系统》

           《操作系统实验指导》

实验代码:

#include "stdafx.h"
#include<stdio.h>
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
const int MAXJOB=100;//
定义表最大记录数
typedef struct node
{
 int front;
 int length;
 char data[20];
}job;
job frees[MAXJOB];//
定义空闲区表
int free_quantity;
job occupys[MAXJOB];//
定义已分配区表
int occupy_quantity;
//
初始化函数
void initial()
{
 int i;
 for(i=0;i<MAXJOB;i++)
 {
  frees[i].front=-1;
  frees[i].length=0;
  strcpy(frees[i].data,"free");
  occupys[i].front=-1;
  occupys[i].length=0;
  strcpy(occupys[i].data," ");
 }
 free_quantity=0;
 occupy_quantity=0;
}
//
创建空闲分区表
int creatfree()
{
 FILE *fp;
 char fname[20];
 cout<<"
请输入空闲区数据文件来源的文件名:";
 cin>>fname;
 if((fp=fopen(fname,"r"))==NULL){
  cout<<"
错误,文件打不开,请检查文件名"<<endl;
 }
 else{
  while(!feof(fp))
  {
   fscanf(fp,"%d\t%d\n",&frees[free_quantity].front,&frees[free_quantity].length);
   free_quantity++;
  }
        cout<<"
空闲的分区表已建立!\n";
  return 1;
 }
 return 0;

}
void sort()//
free空间安首地址从小到大的顺序排列
{
 int i,j,p;
 for(i=0;i<free_quantity-1;i++)
 {
  p=i;
  for(j=i+1;j<free_quantity;j++)
  {
   if(frees[j].front<frees[p].front)
   {
    p=j;
   }
  }
  if(p!=i)
  {
   frees[free_quantity]=frees[i];
   frees[i]=frees[p];
   frees[p]=frees[free_quantity];
  }
 }
}
//
显示函数
void show()
{
 int i;
 cout<<endl<<"----------------------------------------------------------"<<endl;
 cout<<"
当前空闲表:"<<endl;
 cout<<"
起始地址    长度      状态"<<endl;
 for(i=0;i<free_quantity;i++){
  cout.setf(2);
  cout.width(12);
  cout<<frees[i].front;
  cout.width(10);
  cout<<frees[i].length;
  cout.width(8);
  cout<<frees[i].data<<endl;
 }
 cout<<endl<<"----------------------------------------------------------"<<endl;
 cout<<"
当前已分配表:"<<endl;
 cout<<"
起始地址    长度   占用作业名"<<endl;
 for(i=0;i<occupy_quantity;i++)
 {
  cout.setf(2);
  cout.width(12);
  cout<<occupys[i].front;
  cout.width(10);
  cout<<occupys[i].length;
  cout.width(8);
  cout<<occupys[i].data<<endl;
 }
 cout<<endl<<"----------------------------------------------------------"<<endl;
}
//
最先适应分配算法
void assign()
{
 char job_name[20];
 int job_length;
 int i,j,flag,t;
 cout<<"
请输入新申请内存空间的作业名和空间大小:";
 cin>>job_name;
 cin>>job_length;
 flag=0;
 for(i=0;i<free_quantity;i++)
 {
  if(frees[i].length>=job_length)//
如果空闲空间I的长度〉作业长度
  {
   flag=1;     //
空闲标志位就置1
  }
 }
 if(flag==0)
 {
  cout<<endl<<"
对不起,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl;
 }
 else{
  t=0;
  i=0;
  while(t==0)//
为空闲区间的时候
  {
   if(frees[i].length>=job_length)
   {
    t=1;
   }
   i++;//
如果空闲空间I的长度不大于作业长度,I加一,判断下一个空间
  }
  i--;
  occupys[occupy_quantity].front=frees[i].front;//
把已用的空闲空间的首地址负给已用空间的首地址
  strcpy(occupys[occupy_quantity].data,job_name);//
已用空间的内容为作业名
  occupys[occupy_quantity].length=job_length;//
已用空间的长度为作业的长度
  occupy_quantity++;     //
已用空间数量加一
  if(frees[i].length>job_length)//
如果空间的长度大于作业的长度,
  {
   frees[i].front+=job_length;//
空闲空间的起始首地址=原空闲区间的起始长度加作业长度
   frees[i].length-=job_length;//
空闲区间的长度=原空闲区间的长度-作业的长度
  }
  else//
如果空间的长度=作业的长度
&n
bsp; {
   for(j=i;j<free_quantity-1;j++)
   {
    frees[j]=frees[j+1];//
空闲区间前移一位
   }
   free_quantity--;//
空闲区间的数量减一
   cout<<"
内存空间成功:)"<<endl;
  }
 }
}

//撤消作业  
void cancel()
{
 char job_name[20];
 int i,j,flag,p=0;
 int front;
 int length;
 cout<<"
请输入要撤消的作业名:";
 cin>>job_name;
 flag=-1;
 for(i=0;i<occupy_quantity;i++)
 {
  if(!strcmp(occupys[i].data,job_name))//
当输入作业名匹配时
  {
   flag=i;//
i的值赋给flag;
   front=occupys[i].front;//
把已用空间的首地址赋给start
   length=occupys[i].length;//
把已用空间的长度赋给length
  }
 }
 if(flag==-1)
 {
  cout<<"
没有这个作业名"<<endl;
 }
 else
 {//
加入空闲表
  for(i=0;i<free_quantity;i++)
  {
   if((frees[i].front+frees[i].length)==front)//
上空
   {
    if(((i+1)<free_quantity)&&(frees[i+1].front==front+length))//
下空
    {
     frees[i].length=frees[i].length+frees[i+1].length+length;//
i个空闲区间的长度=i个空闲区间的长度+i+1个空闲区间的长度(下空闲区)+length
     for(j=i+1;j<free_quantity;j++)
     {
      frees[j]=frees[j+1];//
后移一位
     }
     free_quantity--;//
空闲区的数量渐少了一个
     p=1;
    }
    else{
     frees[i].length+=length;//
(上空下不空)第i个空闲区间的长度=i个空闲区间的长度+length,空闲区个数不变
     p=1;
    }
   }
   if(frees[i].front==(front+length))//
下空上不空
   {
    frees[i].front=front;//
起始地址等于待回收地址
    frees[i].length+=length;//
i个空闲区间的长度=i个空闲区间的长度+length
    p=1;
   }
  }
  if(p==0)//
上下空闲区都不空(直接在空闲区表中找一个空表目,将其内容插入)
  {
   frees[free_quantity].front=front;
   frees[free_quantity].length=length;
   free_quantity++;//
空闲区的数量加一
  }
  //
删除分配表中的该作业
  for(i=flag;i<occupy_quantity;i++)
  {
   occupys[i]=occupys[i+1];
  }
  occupy_quantity--;//
已用的区的数量
 }
}
void main()
{
 int flag=0;
 int t=1;
 int chioce=0;
 initial();
 flag=creatfree();
 while(flag==1)
 {
  sort();
  cout<<"          
可变分区存储管理模拟系统"<<endl;
     cout<<"   1.
申请空间  "<<endl;
        cout<<"   2.
撤消作业  "<<endl;
        cout<<"   3.
显示空闲表和分配表  "<<endl;
        cout<<"   0.
退出"<<endl;
  cout<<"
请选择:";
  cin>>chioce;
  switch(chioce)
  {
  case 1:
   assign();
   break;
  case 2:
   cancel();
   break;
  case 3:
   show();
   break;
  case 0:
   flag=0;
   break;
  default:
   cout<<"
选择错误!"<<endl;
  }
 }

  评论这张
 
阅读(764)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017