一、实验目的
连续内存分配方式会形成许多“碎片”,虽然可以通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。如果允许将一个进程直接分散地装入到许多不相邻接的分区中,则无需再进行“紧凑”。基于这一思想而产生了离散分配方式。
如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面兑换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入内存后方能运行。
本实验通过程序模拟操作系统的基本分页存储管理方式,进一步理解这一内存分配方式的原理和特点,加深对理论知识的掌握。
二、实验要求
1、用C语言或Java语言编写程序模拟操作系统对内存的基本分页存储管理方式
2、程序要能正确对“内存”进行“分配”和“回收”,能接受用户的输入,显示内存的分配情况,并有一定的容错能力。
3、每个人独立按时完成实验内容。
三、实验内容
本实验假定内存空间已经按块划分,目标程序无需关心内存块大小等底层细节,只需按算法对内存块进行分配即可。程序应该实现以下功能:
1、内存初始化。假定内存块共有N个,初始化后的内存空间应该有一部分已经被使用,这可以用随机数或程序内部的其他算法完成。
2、程序应该能接受用户输入的进程信息,并为之分配内存,返回分配结果(成功或失败),注意,此处应该考虑到不合法的输入并进行相应处理。
3、程序能回收用户指定的进程所占用的内存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。
4、能直观合理地显示内存分配情况。
5、程序界面友好,便于操作和查看运行结果。
#include"stdio.h" #include"stdlib.h"
#include"time.h"
struct wuli{
int wuli_number;
char pname; /*已分配区表登记栏标志,用"0"表示空栏目*/
}; /*内存表*/
struct wuli wuli_table[20]={0};
struct page{
char pname;//进程名称
int psize;//进程大小
int pagetable[10];//进程页表
};//页表
struct page page_table[10]={0};
int allocate(int wulisize,int i,int pagesize);//为进程分配内存空间
int reclaim(int wulisize,char pname);//释放进程占用的空间
void output();
int main()
{
int pagesize;//分页大小
int wulisize=80;//内存大小
char pname;
int xuanze;//操作选择
int i; printf("输入页面大小:\n");
scanf("%d",&pagesize);
//初始化
for(i=0;i<20;i++)
{
wuli_table[i].wuli_number=i;
wuli_table[i].pname='0';
}
for(i=0;i<10;i++)
{
page_table[i].pname='0';
}
//初始化后的内存空间有一部分已经被使用
srand((unsigned)time(NULL));
for(i=0;i<7;i++)
{
int number=rand()%19+1;
wuli_table[number].pname='a';
wulisize--;
}
output();
//进入存储分配
while(wulisize!=0)
{
printf("选择操作\n1.分配 2.回收\n");
scanf("%d",&xuanze);
if(xuanze==1)
{
for( i=0;i<10;i++)
{
if(page_table[i].pname=='0')
{
getchar();
printf("输入进程名称:");
scanf("%c",&page_table[i].pname);
getchar();
printf("输入进程大小:");
scanf("%d",&page_table[i].psize);
break;
}
}
wulisize=allocate(wulisize,i,pagesize);
}else
{
printf("输入进程名称:");
getchar();
scanf("%c",&pname);
wulisize=reclaim(wulisize,pname);
}
output();
}
return 0;
}
int allocate(int wulisize,int i,int pagesize)
{
int k;
int j;
for(k=0;k<(page_table[i].psize/pagesize);k++)
{
for( j=0;j<20;j++)
{
if(wuli_table[j].pname=='0')
{
wuli_table[j].pname=page_table[i].pname;
page_table[i].pagetable[k]=j;
wulisize--;
break;
}
}
}
return wulisize;
}
int reclaim(int wulisize,char pname)
{
int j;
int k;
for( j=0;j<20;j++)
{
if(wuli_table[j].pname==pname)
{
wuli_table[j].pname='0';
wulisize++;
}
}
for (j=0;j<10;j++)
{
if(page_table[j].pname==pname)
{
page_table[j].pname='0';
page_table[j].psize=0;
for(k=0;k<10;k++)
{
page_table[j].pagetable[k]=0;
}
break;
}
}
return wulisize;
}
void