计操实验 分页存储管理 C语言
需求:
假定页面大小为4K,物理内存128M,设计并实现一个内存分配和回收的程序,使用C语言或Python语言编写程序实现这个程序并进行测试。
(1)至少5个进程;
(2)要求有空块管理;
(3)要求有一个逻辑地址到物理地址的变换。
流程图:
//页面大小4K,物理内存128M
//分配、释放内存,逻辑地址到物理地址,空块管理
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define COUNT 32768 //块数量
#define SIZE 4096 //块大小
int BLOCK[COUNT]; //物理块状态 0空闲1占用
int BlankBlockNum=COUNT; //空块数量
typedef struct ProcessList
{
int ID;
int Size;
int Pages;
int Page[100]; //页表
struct ProcessList *next;
}Process;
Process *head=NULL;
void InitProcess()
{
int num,RandomNumber;
printf("请输入进程数:\n");
scanf("%d",&num);
Process *temp;
for(int i=0;i<num;i++)
{
temp = (Process*)malloc(sizeof(Process));
printf("请输入进程的序号、大小:\n");
scanf("%d %d",&temp->ID,&temp->Size);
if(temp->Size%SIZE==0)
{
temp->Pages = temp->Size/SIZE;
}
else
{
temp->Pages = temp->Size/SIZE+1;
}
temp->next = NULL;
//空块管理
if(temp->Pages<BlankBlockNum)
{
BlankBlockNum -=temp->Pages;
}
else
{
printf("内存空间不足,无法分配!\n");
}
//分配内存
for(int j=0;j<temp->Pages;j++)
{
srand(time(0));
while(1)
{
RandomNumber = rand()%32768;
if(BLOCK[RandomNumber]==0)
{
temp->Page[j] = RandomNumber;
BLOCK[RandomNumber] = 1;
break;
}
else
{
continue;
}
}
}
printf("进程%d内存分配成功!页表如下:\n",temp->ID);
printf("页号 物理块\n");
for(int j=0;j<temp->Pages;j++)
{
printf(" %d %d\n",j,temp->Page[j]);
}
//放入进程链表
if(head == NULL)
{
head = temp;
temp = NULL;
}
else
{
Process *temp2;
temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
temp = NULL;
}
}
}
void Release(int id)
{
Process *temp,*temp1,*temp2;
temp = head;
temp1 = head->next;
if(temp->ID == id)
{
for(int i=0;i<temp->Pages;i++)
{
BLOCK[temp->Page[i]] = 0;
BlankBlockNum++;
}
head = temp1;
free(temp);
printf("内存释放成功!\n");
}
else
{
while(temp1)
{
if(temp1->ID == id)
{
for(int i=0;i<temp1->Pages;i++)
{
BLOCK[temp1->Page[i]] = 0;
BlankBlockNum++;
}
printf("内存释放成功!\n");
temp->next = temp1->next;
free(temp1);
break;
}
else
{
temp = temp1;
temp1=temp1->next;
}
}
}
temp2 = head;
printf("现在进程内存分配情况如下:\n");
while(temp2 != NULL)
{
printf("进程%d\n",temp2->ID);
printf("页号 物理块\n");
for(int j=0;j<temp2->Pages;j++)
{
printf(" %d %d\n",j,temp2->Page[j]);
}
temp2 = temp2->next;
}
}
void AddressTranslation(int id,int LogAddress)
{
int PhyAddress,P,W;
Process *temp;
temp = head;
while(temp != NULL)
{
if(temp->ID == id)
{
if(LogAddress > temp->Size)
{
printf("越界中断!\n");
break;
}
else
{
P = LogAddress / SIZE;
W = LogAddress % SIZE;
PhyAddress = temp->Page[P]*SIZE+W;
printf("物理地址为%d\n",PhyAddress);
}
break;
}
else
{
temp = temp->next;
}
}
if(temp == NULL)
{
printf("该进程不存在!\n");
}
}
int main()
{
InitProcess(); //初始化进程并分配内存
Manage();
int n,id,LogAddress;
while(1)
{
printf("请输入要进行的操作序号:1.释放内存 2.查看物理地址 3.退出\n");
scanf("%d",&n);
switch(n)
{
case 1:
printf("请输入要释放的进程ID:\n");
scanf("%d",&id);
Release(id);
break;
case 2:
printf("请输入进程ID和逻辑地址:\n");
scanf("%d %d",&id,&LogAddress);
AddressTranslation(id,LogAddress);
break;
case 3:
exit(0);
break;
default:
printf("Error!\n");
break;
}
}
return 0;
}