实验原理
段页式存储管理是一种将内存划分为多个固定大小的块,每个块可以存储一个页,每个作业由多个段组成,每个段由多个页组成,通过段表和页表来实现作业的存储和地址转换。本实验需要实现作业的分配与回收,包括位示图的初始化、作业的分配、作业的回收等功能。
实现代码
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int M = 1000;
const int N = 64;
bool allocTable[M * N];
int remained;
int MemorySize;
int blockNum;
int blockLength;
int wordLength;
struct PageTable
{
int num;
int block;
};
struct SegmentTable
{
int segmentNum;
string state;
int pageLength;
PageTable pageTable[M];
};
struct Job
{
int size;
string name;
int segmentNum;
SegmentTable segmentTable[M];
struct Job *next;
};
Job *head = NULL;
void printAllocationTable()
{
int i = 0;
cout << "主存位视图如下所示:" << endl;
cout << " ";
for (i = 0; i < wordLength; i++)
cout << setw(2) << i << ' ';
cout << endl << setw(2) << " 0 | ";
for (i = 0; i < blockNum - 1; i++)
{
if ((i + 1) % wordLength == 0)
{
cout << setw(2) << allocTable[i] << endl;
cout << setw(2) << (i + 1) / wordLength << " | ";
}
else
{
cout << setw(2) << allocTable[i] << ' ';
}
}
cout << setw(2) << allocTable[blockNum - 1] << endl;
cout << "剩余物理块数:" << remained << endl;
}
void printPageTable(const Job *job)
{
cout << "作业" << job->name << "的分配情况如下: " << endl;
for (int i = 0; i < job->segmentNum; ++i)
{
cout << "\t" << "第" << i << "段: " << endl;
cout << "\t\t" << "页号\t" << "块号" << endl;
for (int j = 0; j < job->segmentTable[i].pageLength; j++)
{
cout << "\t\t" << job->segmentTable[i].pageTable[j].num << "\t" << job->segmentTable[i].pageTable[j].block
<< endl;
}
}
}
void init()
{
cout << "请输入内存大小为:";
cin >> MemorySize;
cout << "请输入系统字长大小(32/64)为: ";
cin >> wordLength;
cout << "请输入块长: ";
cin >> blockLength;
blockNum = MemorySize / blockLength;
remained = 0;
for (int i = 0; i < blockNum; i++)
{
remained += !(allocTable[i] = rand() % 2);
}
}
void allocation(string name, int size)
{
Job *newJob = new Job;
newJob->name = name;
newJob->size = size;
newJob->next = nullptr;
cout << "请输入要将作业的段数:";
cin >> newJob->segmentNum;
int remainedUnallocSize = size;
for (int i = 0; i < newJob->segmentNum; i++)
{
newJob->segmentTable[i].segmentNum = i;
newJob->segmentTable[i].state = "NO";
cout << "剩余" << remainedUnallocSize << "的内存未分配," << "请输入第" << i << "段的大小: ";
int tmpSegmentSize = 0x7fffffff;
do
{
cin >> tmpSegmentSize;
if (tmpSegmentSize > remainedUnallocSize)
{
cout << "段过大,请重新输入!" << endl;
}
} while (tmpSegmentSize > remainedUnallocSize);
newJob->segmentTable[i].pageLength = tmpSegmentSize;
int j = 0;
for (j = 0; j < tmpSegmentSize; j++)
{
newJob->segmentTable[i].pageTable[j].num = j;
}
int pageNum = 0;
for (j = 0; j < blockNum && pageNum < tmpSegmentSize; j++)
{
if (!allocTable[j])
{
newJob->segmentTable[i].pageTable[pageNum++].block = j;
allocTable[j] = 1;
}
}
remained -= tmpSegmentSize;
remainedUnallocSize -= tmpSegmentSize;
newJob->segmentTable[i].state = "YES";
newJob->next = head;
head = newJob;
cout << "内存分配成功!" << endl;
}
printAllocationTable();
printPageTable(newJob);
}
void recycle(string name)
{
Job *current = head;
Job *previous = NULL;
while (current and current->name.compare(name) != 0)
{
previous = current;
current = current->next;
}
if (current)
{
for (int i = 0; i < current->segmentNum; i++)
{
for (int j = 0; j < current->segmentTable[i].pageLength; j++)
{
allocTable[current->segmentTable[i].pageTable[j].block] = 0;
}
remained += current->segmentTable[i].pageLength;
}
if (previous == NULL)
head = head->next;
else
previous->next = current->next;
delete current;
printAllocationTable();
}
else
{
cout << "未找到对应作业!" << endl;
}
}
int menu()
{
cout << "***************分页式管理***************" << endl;
cout << " * 1. 内存分配 *" << endl;
cout << " * 2. 内存去配 *" << endl;
cout << " * 0. 退出 *" << endl;
cout << "请输入选项:";
int choice;
do
{
cin >> choice;
if (choice != 1 && choice != 2 && choice != 0)
cout << "非法选择!" << endl;
} while (choice != 1 && choice != 2 && choice != 0);
return choice;
}
int main()
{
init();
printAllocationTable();
int choice;
while (1)
{
int choice = menu();
if (choice == 1)
{
printAllocationTable();
cout << "请输入作业名: ";
string name;
cin >> name;
cout << "请输入" << name << "所需主存大小: ";
int size = 0x7FFFFFFF;
cin >> size;
if (size > remained * blockLength)
{
cout << "主存空间不足,无法装载!\n";
continue;
}
else
{
allocation(name, size);
}
}
else if (choice == 2)
{
string name;
printf("请输入作业名:");
cin >> name;
recycle(name);
}
else if (choice == 0)
{
break;
}
}
return 0;
}