// 页面置换算法.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
#include "string.h"
#define MEMORY_BLOCKS 20 //内存物理总块数
#define PROGRAM_PAGES 50 //程序分页数上限
#define PAGE_USE_LONGTH 100 //页面走向长度最大值
#define FIFO 1 //先进先出置换
#define LRU 2 //最久未用置换
int memory_blocks=0; //分配内存物理块数
int program_pages=0; //程序分页数
int memory_allocation[MEMORY_BLOCKS]; //内存分配情况
struct VISIT { //访问字段
int load_time; //装载时间
int frequency; //使用频率的顺序,0为最高
};
struct PAGR_LIST { //页表
int page_num; //页号
int block_num; //物理块号
bool state; //状态位
bool modify; //修改位
struct VISIT visit; //访问字段
int disk; //外存地址
}page_list[PROGRAM_PAGES];
int create_rand(int a, int b);
void init(int m, int p);
void page_adjust(int p);
bool allocation_once(int p, int f);
int change_page(int f);
void huanhang(int l);
void show_me();
void simulation(int l, int f);
void menu();
int create_rand(int a, int b) { //生成随机数
int r;
r = rand() % (b - a+1) + a;
//printf("%d",r);
return r;
}
void init(int m,int p) {
memory_blocks = m;
program_pages = p;
for (int i = 0; i < memory_blocks ; i++) {
memory_allocation[i] = -1;
}
for (int i = 0; i < program_pages ; i++) {
page_list[i].page_num = i;
page_list[i].block_num = -1;
page_list[i].state = false;
page_list[i].modify = false;
page_list[i].visit.load_time = 0;
page_list[i].visit.frequency = -1;
}
printf("\n初始化完成\n");
}
void page_adjust(int p) { //内存中其他页的调整
for (int i = 0; i <program_pages; i++) {
if (page_list[i].state == true) { //内存中的页
page_list[i].visit.load_time += 1;
if (page_list[p].visit.frequency == -1) { //该页不在内存
page_list[i].visit.frequency += 1;
}
else { //该页在内存
if (page_list[i].visit.frequency < page_list[p].visit.frequency) {
page_list[i].visit.frequency += 1;
}
}
}
}
}
bool allocation_once(int p,int f){ //单次访问 p为要访问的页,f为置换算法
bool reg = false; //访问成功的标记
if (page_list[p].state == false) { //该页未在内存中
for (int i = 0; i < memory_blocks; i++) {
if (memory_allocation[i] == -1) { //有内存块可供分配
reg = true;
page_adjust(p); //调整当前顺序
memory_allocation[i] = p;
page_list[p].block_num = i;
page_list[p].state = true;
page_list[p].visit.load_time += 1;
page_list[p].visit.frequency = 0;
break;
}
}
}
else { //该页已在内存中
reg = true;
page_adjust(p);
page_list[p].visit.frequency = 0;
}
if (reg == false) { //需要置换
change_page(f);
}
return reg;
}
int change_page(int f) { //页面置换算法
int out = -1; //被换出的页号
int block = -1; //空出的物理块号
if (f == FIFO) {
for (int i = 0; i < memory_blocks; i++) {
if (page_list[memory_allocation[i]].visit.load_time > out) {
out = page_list[memory_allocation[i]].visit.load_time;
block = i;
}
}
out = memory_allocation[block];
}
else if(f == LRU){
for (int i = 0; i < memory_blocks; i++) {
if (page_list[memory_allocation[i]].visit.frequency == memory_blocks-1) {
block = i;
break;
}
}
out= memory_allocation[block];
}
//收尾操作
memory_allocation[block] = -1;
page_list[out].block_num = -1;
page_list[out].state = false;
page_list[out].visit.load_time = 0;
page_list[out].visit.frequency = -1;
return out;
}
void huanhang(int l){ //换行(页表显示用)
printf("\n+--------");
for (int i = 0; i<l; i++)
printf("-----");
printf("+\n");
}
void show_me() { //页表显示
if (memory_blocks != 0 && program_pages != 0) {
printf("\n 内存表");
huanhang(memory_blocks);
printf("| 块号 |");
for (int i = 0; i < memory_blocks; i++) {
printf("%3d |", i);
}
huanhang(memory_blocks);
printf("| 页号 |");
for (int i = 0; i < memory_blocks; i++) {
printf("%3d |", memory_allocation[i]);
}
huanhang(memory_blocks);
printf("\n 页表");
huanhang(program_pages);
printf("| 页号 |");
for (int i = 0; i < program_pages; i++) {
printf("%3d |",i);
}
huanhang(program_pages);
printf("|物理块号|");
for (int i = 0; i < program_pages; i++) {
printf("%3d |", page_list[i].block_num);
}
huanhang(program_pages);
printf("| 状态位 |");
for (int i = 0; i < program_pages; i++) {
if(page_list[i].state==true)
printf(" y |");
else
printf(" n |");
}
huanhang(program_pages);
printf("| 修改位 |");
for (int i = 0; i < program_pages; i++) {
if (page_list[i].modify == true)
printf(" y |");
else
printf(" n |");
}
huanhang(program_pages);
printf("|装载时间|");
for (int i = 0; i < program_pages; i++) {
printf("%3d |", page_list[i].visit.load_time);
}
huanhang(program_pages);
printf("|频率顺序|");
for (int i = 0; i < program_pages; i++) {
printf("%3d |", page_list[i].visit.frequency);
}
huanhang(program_pages);
}
else {
printf("\n尚未初始化,请先初始化数据\n");
}
}
void simulation(int l,int f) { //模拟操作
init(memory_blocks, program_pages);
int lose = 0;
int longth[PAGE_USE_LONGTH];
for (int i = 0; i < l; i++) {
int a;
a=create_rand(0,program_pages-1);
longth[i] = a;
bool flag;
flag = allocation_once(a, f);
if (flag == false) {
lose += 1;
allocation_once(a, f);
}
}
float m;
float Lose = lose;
float L = l;
m = Lose / L;
printf("\n随机访问序列为(页号) ");
for (int i = 0; i < l; i++) {
printf("%3d",longth[i]);
}
printf("\n\n缺页率为%.2f%%\n",m*100);
}
void menu(){ //菜单函数
printf("\n 页面置换模拟\n");
printf("\n初始化(init) 显示页表信息(show) 页面置换算法(FIFO)或(LRU) \n清屏(clear)\n");
char code[20];
while (1) {
printf("\n");
scanf("%s", code);
if (_stricmp(code, "init") == 0) { //初始化
memory_blocks = 0;
program_pages = 0;
int a, b;
printf("\n请输入进程的分页数(最大%d) ", PROGRAM_PAGES);
scanf("%d", &a);
while (a > PROGRAM_PAGES||a<1) {
printf("\n输入数值非法,请重新输入", PROGRAM_PAGES);
scanf("%d", &a);
}
printf("\n请输入为该进程分配的物理块数(最大%d) ", MEMORY_BLOCKS);
scanf("%d", &b);
while (b > MEMORY_BLOCKS||b<1) {
printf("\n输入数值非法,请重新输入", MEMORY_BLOCKS);
scanf("%d", &b);
}
init(b,a);
}
else if (_stricmp(code, "show") == 0) { //显示功能
show_me();
}
else if (_stricmp(code, "FIFO") == 0) { //先进先出置换
int l;
printf("\n请输入页面走向长度 ");
scanf("%d",&l);
simulation(l,FIFO);
}
else if (_stricmp(code, "LRU") == 0) { //最久未用置换
int l;
printf("\n请输入页面走向长度 ");
scanf("%d", &l);
simulation(l, LRU);
}
else if (_stricmp(code, "clear") == 0) { //清屏
system("cls");
printf("\n 页面置换模拟\n");
printf("\n初始化(init) 显示页表信息(show) 页面置换算法(FIFO)或(LRU) \n清屏(clear)\n");
}
else printf("命令无效,请重新输入\n");
}
}
int main()
{
srand(time(NULL));
menu();
getchar();
return 0;
}
操作系统之——页面置换算法C语言实现
最新推荐文章于 2021-05-21 16:45:37 发布