实验四 存储器管理综合实验
实验四 存储器管理综合实验
实验目的
- 掌握LINUX中动态申请内存的方法;理解多任务环境下存储管理的重要性以及基本存储管理实现方法;
- 理解虚拟存储管理实现基本原理以及页面淘汰算法对虚拟存储器性能影响及页面淘汰算法的实现。
实验工具及环境
- LINUX系统网络环境或单机,gcc编译器。Windows系统网络环境+远程SSH客户端软件。
实验内容
- (1)编写一个程序申请两块大小为10的内存,分别存放字符串“123456789”和“987654321”,并输出字符串及存放地址,然后重新调整内存大小为20,再次输出地址。使用键盘命令查看程序执行前后的内存使用情况。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <malloc.h>
int main(void)
{
char *str;
if (str = (char *)malloc(10 * sizeof(char))) /*申请大小为10的内存*/
{
printf("Not enough memory to allocate buffer\n");
exit(1);
}
strcpy(str,"123456789");
printf("String is %s\n %p\n",str,str);
if(str = (char *)malloc(20 * sizeof(char))) /*重新调整内存大小为20*/
{
printf("Not enough memory to reallocate buffer\n");
exit(1);
}
strcpy(str,"987654321");
printf("String is %s\n %p\n",str,str);
free(str);
return(0);
}
- (2)利用C语言,编程实现先进先出、OPT、LRU中的一个算法,开发一个虚拟存储器的模拟程序,实现虚拟存储器的页面调度,页面序列从指定的数组或文本文件(TXT文件)中取出;输出:页面调度顺序,内存物理块中页面变化情况,缺页的总次数和缺页率。
#include<stdio.h>
#define M 4
#define N 17
#define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|\n") // 表格控制
typedef struct page
{
int num; // 记录页面号
int time; // 记录调入内存时间
}Page; // 页面逻辑结构,结构为方便算法实现设计
Page b[M]; // 内存单元数
int c[M][N]; // 暂保存内存当前的状态:缓冲区
int queue[100]; // 记录调入队列
int K; // 调入队列计数变量
// 初始化内存单元、缓冲区
void Init(Page *b,int c[M][N])
{
int i,j;
for(i=0;i<N;i++)
{
b[i].num=-1; // 初始化内存单元
b[i].time=N-i-1;
}
for(i=0;i<M;i++)
for(j=0;j<N;j++)
c[i][j]=-1; // 初始化缓冲区
}
// 取得在内存中停留最久的页面,默认状态下为最早调入的页面
int GetMax(Page *b)
{
int i;
int max=-1;
int tag=0;
for(i=0;i<M;i++)
{
if(b[i].time>max)
{
max=b[i].time;
tag=i;
}
}
return tag;
}
// 判断页面是否已在内存中
int Equation(int fold,Page *b)
{
int i;
for(i=0;i<M;i++)
{
if (fold==b[i].num)
return i;
}
return -1;
}
// LRU核心部分
void Lru(int fold,Page *b)
{
int i;
int val;
val=Equation(fold,b);
if (val>=0)
{
b[val].time=0;
for(i=0;i<M;i++)
if (i!=val)
b[i].time++;
}
else
{
queue[++K]=fold; // 记录调入页面
val=GetMax(b); //取得在内存中停留最久的页面
b[val].num=fold;
b[val].time=0;
for(i=0;i<M;i++)
if (i!=val)
b[i].time++;
}
}
// 主程序
void main()
{
int a[N]={1,0,1,0,2,4,1,0,0,8,7,5,4,3,2,3,4};
int i,j;
start:
K=-1;
Init(b, c);
for(i=0;i<N;i++)
{
Lru(a[i],b);
c[0][i]=a[i];
// 记录当前的内存单元中的页面
for(j=0;j<M;j++)
c[j][i]=b[j].num;
}
// 结果输出
printf("内存状态为:\n");
Myprintf;
for(j=0;j<N;j++)
printf("|%2d ",a[j]);
printf("|\n");
Myprintf;
for(i=0;i<M;i++)
{ for(j=0;j<N;j++)
{
if(c[i][j]==-1)
printf("|%2c ",32);
else
printf("|%2d ",c[i][j]);
}
printf("|\n");
}
Myprintf;
printf("\n调入队列为:");
for(i=0;i<K+1;i++)
printf("%3d",queue[i]);
printf("\n缺页次数为:%6d\n缺页率:%16.6f",K+1,(float)(K+1)/N);
printf("\nAre you continuing!\ty?");
system("stty echo");
if(getchar()=='y')
goto start;
}
- (3)选做:利用C语言,实现存储分配算法,开发一个存储管理的模拟程序,对内存空间的管理和分配。内存空间的管理采用分区管理方式。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define total_page_address 640 // 作业的地址流数
#define total_page 32 // 作业的页面数
int page[total_page_address];
void FIFO(int mem_frame);
void LRU(int mem_frame);
void OPT(int mem_frame);
main()
{
int i,p,fl;
srand(getpid()); // 设置随机种子
// 产生页地址流,假设有50%的指令是顺序执行的
for (i=0;i<total_page_address;i++)
page[i]=-1;
for (i=0;i<total_page_address;i+=2)
{
fl=0;
while (fl==0)
{
p=rand()%total_page_address;
if (page[p]==-1) fl=1;
}
page[p]=rand()%total_page;
}
p=0;
for (i=0;i<total_page_address;i++)
{
if (page[i]==-1)
page[i]=p;
else
p=page[i];
}
for (i=4;i<=32;i++) // 用户内存工作区从4 个页面到32 个页面
{
printf("%2d page frames ",i);
FIFO(i); // 调用FIFO
LRU(i); // 调用LRU
OPT(i); // 调用OPT
printf("\n");
}
}
void FIFO(int mem_frame)
{
int page_message[100],i,ptr=0,j;
int invalid=0,exist;
// page_message 存放页面信息,ptr指向最早进入的页面
for (i=0;i<100;i++) page_message[i]=-1; // -1表示无页面
for (i=0;i<total_page_address;i++)
{
//查找该页是否在内存
exist=0;
for (j=0;j<mem_frame;j++)
if (page_message[j]==page[i])
exist=1; //该页在内存中
if (exist==0) //该页不在内存中,失败
{
invalid++;
for (j=0;j<mem_frame;j++)
if (j==mem_frame) //是否有空闲内存块
{
page_message[j]=page[i]; //如果有装入对应的页面
break;
}
if (j>=mem_frame)
{
page_message[ptr]=page[i]; //淘汰最早进入的页面
ptr=(ptr+1) % mem_frame;
}
}
}
printf("FIFO: %6.4f ",1-(float)invalid/total_page_address);
}
void LRU(int mem_frame)
{
int page_message[100],i,ptr=0,j,m,n;
int invalid=0,exist,sit1,sit2;
// page_message 存放页面信息,ptr指向最早进入的页面
for (i=0;i<100;i++) page_message[i]=-1; // -1表示无页面
for (i=0;i<total_page_address;i++)
{
//查找该页是否在内存
exist=0;
for (j=0;j<mem_frame;j++)
if (page_message[j]==page[i])
exist=1; //该页在内存中
if (exist==0) //该页不在内存中,失败
{
invalid++;
for (j=0;j<mem_frame;j++)
if (page_message[j]==-1) //是否有空闲内存块
{
page_message[j]=page[i]; //如果有装入对应的页面
break;
}
if (j>=mem_frame)
{
//查找最久未用页面进行淘汰
exist=3333;
for (m=0;m<mem_frame;m++)
{
for(n=i-1;n>=0;n--)
if(page_message[m]==page[n]) {
sit1=n;
break;
}
if (exist>sit1) {
exist=sit1;
sit2=m;
}
}
page_message[sit2]=page[i];
}
}
}
printf("LRU: %6.4f ",1-(float)invalid/total_page_address);
}
void OPT(int mem_frame)
{
int page_message[100],i,ptr=0,j,m,n;
int invalid=0,exist,sit1,sit2;
// page_message 存放页面信息,ptr指向最早进入的页面
for (i=0;i<100;i++) page_message[i]=-1; // -1表示无页面
for (i=0;i<total_page_address;i++)
{
//查找该页是否在内存
exist=0;
for (j=0;j<mem_frame;j++)
if (page_message[j]==page[i])
exist=1; //该页在内存中
if (exist==0) //该页不在内存中,失败
{
invalid++;
for (j=0;j<mem_frame;j++)
if (page_message[j]==-1) //是否有空闲内存块
{
page_message[j]=page[i]; //如果有装入对应的页面
break;
}
if (j>=mem_frame)
{
//查找最久未用页面进行淘汰
exist=-1;
for (m=0;m<mem_frame;m++)
{
for(n=i+1;n<total_page_address;n++)
if(page_message[m]==page[n]) {
sit1=n;
break;
}
if (n>=total_page_address)
sit2=m;
else
if (exist<sit1) {
exist=sit1;
sit2=m;
}
}
page_message[sit2]=page[i];
}
}
}
printf("LRU: %6.4f ",1-(float)invalid/total_page_address);
}
欢迎查阅