操作系统 LRU页面置换算法

写这个算法,就是一步一步调试出来的,花点功夫,其实原理比较简单,我使用的是链表。
中间有一些循环控制变量和条件需要琢磨以下,其他还好。

#define vpNum 10	//虚页块数
#define rpNum 3		//实页块数
ElemType arr[N] = { 7,0,1,2,0,3,4,2,3,0,3,2,1,2,0,1,7,0,1 };//页面引用串

完成这个分了三种情况:

第一种情况,虚页号和页面号引用串值相等且此时不在内存中
第二种情况,如果实页满了,进行页面置换
第三种情况,此时刻的页面号在内存中

完整代码:

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define vpNum 10	//虚页块数
#define rpNum 3		//实页块数
#define N 20		//页面引用串数目
#define MAX 100		//用于找最小访问时间的对比量,初值设置大一点
ElemType arr[N] = { 7,0,1,2,0,3,4,2,3,0,3,2,1,2,0,1,7,0,1 };//页面引用串
int count = 0;		//记录一共多少次缺页
int sum = 1;		//记录时刻
// 虚页数据结构
typedef struct VirtualPage {
	ElemType virtualPage;	//虚页号
	ElemType realPage;		//实页号
	ElemType state;			//状态
	ElemType enterTime;		//进入时间
	ElemType accessTime;	//访问时间
	struct VirtualPage* next;
	int len;
}VirtualPage, * VP;
// 实页数据结构
typedef struct RealPage {
	ElemType realPage;		//实页号
	ElemType virtualPage;	//虚页号
	ElemType state;			//状态
	struct RealPage* next;
	int len;
}RealPage, * RP;
//初始化虚页数据结构,尾插法
void init_VP(VP& vp) {
	vp = (VP)malloc(sizeof(VirtualPage));
	VP q, r = vp;
	vp->len = vpNum;
	for (int i = 0; i < vp->len; i++) {
		q = (VP)malloc(sizeof(VirtualPage));
		q->virtualPage = i;
		q->realPage = -1;
		q->state = 0;
		q->enterTime = 0;
		q->accessTime = 0;
		r->next = q;
		r = q;
	}
	r->next = NULL;
}
//初始化虚页数据结构,尾插法
void init_RP(RP& rp) {
	rp = (RP)malloc(sizeof(RealPage));
	RP q, r = rp;
	rp->len = rpNum;
	for (int i = 0; i < rp->len; i++) {
		q = (RP)malloc(sizeof(RealPage));
		q->realPage = i;
		q->virtualPage = -1;
		q->state = 0;
		r->next = q;
		r = q;
	}
	r->next = NULL;
}
//记录每个时刻为哪个页面上内存
void print(VP vp) {
	printf("***************************************************\n");
	printf("\n时刻%d:\n", sum++);
	printf("页面%d装入内存\n", vp->virtualPage);
	printf("%3d", vp->virtualPage);
	printf("\t%3d", vp->realPage);
	printf("\t%3d", vp->state);
	printf("\t%3d", vp->enterTime);
	printf("\t\t%3d\n", vp->accessTime);
}
//打印虚页 实页当前时刻状态
void showAns(VP vp, RP rp) {
	vp = vp->next;
	rp = rp->next;
	printf("\n虚页号\t实页号\t状态\t加入时间\t访问时间\n");
	while (vp != NULL) {
		printf("%3d", vp->virtualPage);
		printf("\t%3d", vp->realPage);
		printf("\t%3d", vp->state);
		printf("\t%3d", vp->enterTime);
		printf("\t\t%3d\n", vp->accessTime);
		vp = vp->next;
	}

	printf("\n实页号\t虚页号\t状态\n");
	while (rp != NULL) {
		printf("%3d", rp->realPage);
		printf("\t%3d", rp->virtualPage);
		printf("\t%3d\n", rp->state);
		rp = rp->next;
	}
	printf("\n");
}
//LRU页面置换算法
void function(VP vp, RP rp, ElemType arr[]) {
	//创建的是带头结点的链表,所以指向头结点的下一个节点为 0号 节点的值
	VP v = vp->next;
	RP r = rp->next;
	bool flag = false;//控制缺页置换操作完成后 跳出循环
	for (int i = 0; i < N; i++) {
		while (v != NULL) {
			flag = false;//每次循环都要重置flag
			//第一种情况,虚页号和页面号引用串值相等且此时不在内存中
			if (v->virtualPage == arr[i] && v->state == 0) {
				//如果实页没满,直接装入内存
				if (count < rpNum) {
					v->state = 1;//状态置为1
					while (r != NULL) {
						if (r->state == 0) {//找一个实页中的空块
							r->state = 1;	//状态置为1
							//修改虚页,实页中相关属性,与之对应
							r->virtualPage = v->virtualPage;
							v->realPage = r->realPage;
							v->enterTime = i + 1;
							v->accessTime = i + 1;
							flag = true;//标志找到一个空块
							print(v);
							showAns(vp, rp);
							count++;	//缺页次数加一
							break;
						}
						r = r->next;//没找到符合要求的节点,继续向下找
					}
				}
				//第二种情况,如果实页满了,进行页面置换
				else {
					VP temp = vp->next;
					VP t = (VP)malloc(sizeof(VirtualPage));//临时节点,用来找到访问时间最小的节点
					t->accessTime = MAX;
					while (temp != NULL) {
						//比大小
						if (temp->accessTime < t->accessTime && temp->state == 1) {
							t = temp;
						}
						temp = temp->next;
					}
					v->state = 1;//置换的页面状态改为1
					t->state = 0;//被置换的页面状态改回0
					while (r != NULL) {
						//通过虚页的实页号找到实页中对应的实页块,并修改对应参数
						if (t->realPage == r->realPage && r->state == 1) {
							v->realPage = t->realPage;
							t->realPage = -2;//表示装入过内存
							v->enterTime = i + 1;
							v->accessTime = i + 1;
							r->virtualPage = v->virtualPage;
							flag = true;//标志替换成功
							print(v);
							showAns(vp, rp);
							count++;
							break;
						}
						r = r->next;
					}
				}
			}
			//第三种情况,此时刻的页面号在内存中
			else if (v->virtualPage == arr[i] && v->state == 1) {
				v->accessTime = i + 1;//修改访问时间
				flag = true;//标志操作完成
				print(v);
				showAns(vp, rp);
				break;
			}
			if (flag) break;//三种情况中,任一种成功就直接判断下一个页面号,不成功再判断下一个虚页块是否满足要求
			v = v->next;
		}
		//用于回到链表头。进行重新比对
		v = vp->next;
		r = rp->next;
	}
}
int main() {
	VP vp;
	init_VP(vp);
	RP rp;
	init_RP(rp);
	function(vp, rp, arr);
	showAns(vp, rp);
	int s = count + 1;
	printf("\n该访问序列的缺页率为:%.2f%c\n\n\n\n",(s*1.0/N)*100,'%');
	return 0;
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值