操作系统之——页面置换算法C语言实现

// 页面置换算法.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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值