操作系统之FIFO和LRU

实验题目:

(一)、模拟请求分页式存储管理中硬件的地址转换和产生缺页中断。

(二)、用先进先出页面调度算法处理缺页中断。

(三)、用最近最少用页面调度算法处理缺页中断。

代码如下:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#define m 4

typedef struct pagetable {

	int pagenum;		//页号
	int flag;			//标志	1.装入主存		0.没有
	int cachenum;		//主存块号
	int changeFlag;		//修改标志	1.修改过。	0.没有
	char location[5];		//在磁盘上的位置
	
}pagetable;

typedef struct order{

	char name[2];
	int page;
	char unitNum[3];

}order;

void readOrder(order ord[])
{
	char filename[10] ;
	int j  = 0;
	
	FILE *fp = NULL;
	printf("请输入order的文件名:");
	scanf("%s:", filename);

	fp = fopen(filename,"r");		//只读
	if( fp== NULL)
	{
		printf("错误!");
		exit(1);
	}
	printf("指令:\n");
	printf(" %-8s %-8s %-8s \n", "操作","页号","单元号");
	for(j ;j<12;j++)					//不能再for内部定义变量		文件中是否也不能定义?
    {
		fscanf(fp," %s %d %s  ", ord[j].name,&ord[j].page,ord[j].unitNum);
		printf(" %-8s %-8d %-8s \n", ord[j].name,ord[j].page,ord[j].unitNum);
    }
	fclose(fp);		//关闭文件
	fp = NULL;		//需要指向空,否则会指向原打开文件地址
}


void readPageTable(pagetable pt[])
{
	char filename[10] ;
	int j  = 0;
	
	FILE *fp = NULL;
	printf("请输入页表的文件名:");
	scanf("%s:", filename);

	fp = fopen(filename,"r");		//只读
	if( fp== NULL)
	{
		printf("错误!");
		exit(1);
	}
	printf("页表信息:\n");
	printf(" %-8s %-8s %-8s %-8s %-8s\n", "页号","驻留标志","主存块号","修改标志","外存地址");
	for(j ;j<7;j++)
    {
		fscanf(fp," %d %d %d %d %s ", &pt[j].pagenum,&pt[j].flag,&pt[j].cachenum,&pt[j].changeFlag,&pt[j].location);
		printf(" %-8d %-8d %-8d %-8d %-8s \n",pt[j].pagenum,pt[j].flag,pt[j].cachenum,pt[j].changeFlag,pt[j].location);
    }
	fclose(fp);		//关闭文件
	fp = NULL;		//需要指向空,否则会指向原打开文件地址
}

void absolulyAddress(order* ord, pagetable* pt )
{

	//绝对地址=块号×块长+单元号
	
	int i = ord->page;
	//块号默认为128是2的幂次,所以高地值为块号,底地址为单元号
	
	printf("address=%d%s\n\n",pt->cachenum,&ord->unitNum);

}

// 1. 求分页式存储管理中硬件的地址转换和产生缺页中断
void firstMethod(order ord[], pagetable pt[]){
	int i = 0;
	
	printf("\n\n\n----------------  1  ----------------\n\n");
	
	for(i ;i<12;i++)
	{
		
		printf("“%s”的页号为%d  单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum);
		
		if(pt[ord[i].page].flag==1){			//已在主存中
			printf("该页已经在主存。绝对地址为:");
			absolulyAddress(&ord[i],&pt[ord[i].page]);
		}
		else if(pt[ord[i].page].flag==0)		//该页不在主存		产生中断信号
		{
			printf("该页不在主存。产生中断信号:\n");
			printf("*%d\n\n" , pt[ord[i].page].pagenum);		//中断信号
			pt[ord[i].page].flag = 1;			//把该页信息从磁盘读出装入主存
			pt[ord[i].page].cachenum = 10;		//装入主存中,主存块号 设为10
			i--;								//重新执行该指令
		}
		
	}

}

// 2. FIFO页面调度算法处理缺页中断
void FIFOMethod(order ord[], pagetable pt[]){
	int i = 0;
	int j = 0;
	int k = 0;
	int p[m];
	printf("\n\n\n----------------  2  ----------------\n\n");
	
	//初始化P
	for (i;i<m;i++)
	{
		p[i] = i;
	}

	i = 0;

	for(i ;i<12 ;i++)
	{
		printf("“%s”的页号为%d  单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum);

		if(pt[ord[i].page].flag==1){			//如果该页标志是1
			if (strcmp(ord[i].name, "存") == 0)
			{
				pt[ord[i].page].changeFlag = 1;
			}
			printf("该页已在主存, 其绝对地址为:");
			absolulyAddress(&ord[i],&pt[ord[i].page]);
		}
		else if(pt[ord[i].page].flag==0)		//如果该页标志不是1
		{
			printf("该页不在主存。产生中断信号  *%d\n" ,pt[ord[i].page].pagenum);	//中断信号
			j = p[k];

			if (pt[j].changeFlag == 1)		//如果该页被修改过, 则将该页换出,将新页换入。
			{
				printf("%d 页被换出, ",j);
				printf("%d 页被换入 \n\n", ord[i].page);
			}else if (pt[j].changeFlag == 0)
			{
				printf("%d 页被覆盖, ",j);
				printf("%d 页被换入 \n\n", ord[i].page);
			}
			
			pt[ord[i].page].flag = 1;
			pt[ord[i].page].cachenum = pt[p[k]].cachenum;
			pt[p[k]].flag = 0;

			//修改K的值
			p[k] = ord[i].page;
			k = (k+1)%m;

			i--;
		}
	}

	//输出P
	i = 0;
	for (i;i<m;i++)
	{
		printf("p数组的值为: \n");
		printf("P[i] = %d\n", p[i]);
	}
	printf("\n");

}

// 3. LRU页面调度算法处理缺页中断
void LRUMethod(order ord[], pagetable pt[]){
	int i = 0;
	int n = m-1;
	int p[m];
	printf("\n\n\n----------------  3  ----------------\n\n");
	
	//初始化P
	for (i;i<m;i++)
	{
		p[i] = m-i-1;
	}
	
	i = 0;
	
	for(i ;i < 12 ;i++)
	{
		printf("“%s”的页号为%d  单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum);
		
		if(pt[ord[i].page].flag==1){			//如果该页标志是1
			if (strcmp(ord[i].name, "存") == 0)
			{
				pt[ord[i].page].changeFlag = 1;
			}
			printf("该页已在主存, 其绝对地址为:");
			absolulyAddress(&ord[i],&pt[ord[i].page]);

			if (p[0] != ord[i].page)//判断当前运行的页面和P数组的开头是否相等。
			{
				n = m-1;
				for (n; n > 0; n--)
				{
					p[n] = p[n-1];
				}
				p[0] = ord[i].page;
	
			}
		
		}
		else if(pt[ord[i].page].flag==0)		//如果该页标志不是1
		{
			printf("该页不在主存。产生中断信号  *%d\n" ,pt[ord[i].page].pagenum);	//中断信号
			
			//更改当前页号的主存块号和标志
			pt[ord[i].page].flag = 1;
			pt[ord[i].page].cachenum = pt[p[m-1]].cachenum;
			pt[p[m-1]].flag = 0;//更改被替换的页号的标志

			printf("%d页被换出,%d页被换入\n\n", p[m-1], ord[i].page);

			n = m-1;
			for (n; n > 0; n--)
			{
				p[n] = p[n-1];
			}
			p[0] = ord[i].page;

			i--;

		}

	}
	
	printf("\n");
	//输出P
	i = 0;
	for (i;i<m;i++)
	{
		printf("p数组的值为: \n");
		printf("P[i] = %d\n", p[i]);
	}
	printf("\n");
}

int main(){

	order ord[12] ;				//把指令存放到ord数组中
	pagetable pt[7];			//把页表存放到pt数组中

	readOrder(ord);
	readPageTable(pt);

	//第一个
//	firstMethod(ord, pt);
	//第二个
//	FIFOMethod(ord, pt);
	//第三个
	LRUMethod(ord, pt);

	return 0;
}

a.txt 如下:

+ 0 70
+ 1 50
* 2 15
存 3 21
取 0 56
- 6 40
移位 4 053
+ 5 023
存 1 037
取 2 078
+ 4 001
存 6 084


b.txt 如下:

0 1 5 0 011
1 1 8 0 012
2 1 9 0 013
3 1 1 0 021
4 0 -1 0 022
5 0 -1 0 023
6 0 -1 0 121

OVER! 

请大家指出错误和不足。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值