#include <stdio.h>
#include <stdlib.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define INVALID -1 //-1表示缺页
页表结构类型
typedef struct pl_type {
int pn; //页号
int fn; //页面号
int time; //访问时间
int dist; //下次访问离当前页的距离
}pl_type;
//页面链结构类型
typedef struct fl_type {
int pn; //页号
int fn; //页面号
struct fl_type *next; //链接指针
}fl_type;
//结构变量
pl_type pl[512]; //页表
fl_type fl[512],*free_head,*busy_head,*busy_tail; //页面
int page[512]; //访问串(访问的页号序列)
int total_pages; //访问串长度
int diseffect; //缺页数
//初始化函数
//形参frame_number为分配给用户进程的内存页面数
void initialize(int frame_number)
{
int i;
diseffect=0; //页故障数初始化为0
//建立空页表
for(i=0;i<512;i++) {
pl[i].pn=i; //页号
pl[i].fn=INVALID; //页面号为空,(开始时,页还未装入到页面)
pl[i].time=0; //时间为0
}
//建立空闲页面链
for(i=1;i<frame_number;i++) {
fl[i-1].next=&fl[i]; //建立fl[i-1]和fl[i]间的链接
fl[i-1].fn=100+i-1;//页面号由系统分配,可以是其他值,例如从100开始,fl[i-1].fn=100+i-1;
}
fl[frame_number-1].next=NULL; //链表末尾为空指针
fl[frame_number-1].fn=100+frame_number-1; //末尾结点的页面号
free_head=&fl[0]; //空页面队列的头指针指向fl[0]
}
//OPT函数:计算OPT算法下的缺页率
void OPT(int frame_number)
{
int i;
initialize(frame_number); //初始化页表和页面链
busy_head=free_head;
for(i=0; i<total_pages; i++) {
if(pl[page[i]].fn==INVALID) { //查页表,若缺页
diseffect++; //记录缺页数
if(free_head==NULL){ //若无空闲页面, 下面3句置换忙页面链头结点
pl[busy_head->pn].fn=INVALID; //淘汰忙页面链头结点
busy_head->pn=page[total_pages%(i+total_pages/2)]; //忙页面链头结点装入新页
pl[page[total_pages%(i+total_pages/2)]].fn=busy_head->fn; //修改页表
busy_tail->next=busy_head; //这4句把忙页面链头结点移动到尾部
busy_head=busy_head->next;
busy_tail=busy_tail->next;
busy_tail->next=NULL;
}else{ //若有空闲页面, 下面3句直接装入新页
free_head->pn=page[i]; //空闲页面链头结点装入新页
pl[page[i]].fn=free_head->fn; //修改页表
free_head=free_head->next; //空闲页面链头指针前移
if(free_head) busy_tail=free_head; //记录忙页面链尾结点
}
}
}
//打印结果
printf("OPT: %02d次(缺页数(缺页率)为%.02f%% 命中率为%.02f%%)",diseffect,100.0*diseffect/total_pages,100-100.0*diseffect/total_pages);
}
//FIFO函数:计算FIFO算法下的缺页率
void FIFO(int frame_number)
{
int i;
initialize(frame_number); //初始化页表和页面链
busy_head=free_head;
for(i=0; i<total_pages; i++) {
if(pl[page[i]].fn==INVALID) { //查页表,若缺页
diseffect++; //记录缺页数
if(free_head==NULL){ //若无空闲页面, 下面3句置换忙页面链头结点
pl[busy_head->pn].fn=INVALID; //淘汰忙页面链头结点
busy_head->pn=page[i]; //忙页面链头结点装入新页
pl[page[i]].fn=busy_head->fn; //修改页表
busy_tail->next=busy_head; //这4句把忙页面链头结点移动到尾部
busy_head=busy_head->next;
busy_tail=busy_tail->next;
busy_tail->next=NULL;
}else{ //若有空闲页面, 下面3句直接装入新页
free_head->pn=page[i]; //空闲页面链头结点装入新页
pl[page[i]].fn=free_head->fn; //修改页表
free_head=free_head->next; //空闲页面链头指针前移
if(free_head) busy_tail=free_head; //记录忙页面链尾结点
}
}
}
//打印结果
printf("FIFO: %02d次(缺页数(缺页率)为%.02f%% 命中率为%.02f%%)",diseffect,100.0*diseffect/total_pages,100-100.0*diseffect/total_pages);
}
//输入访问串
void Input_reference_string(void)
{
int i;
printf("输入的访问串,页号间以空格分开。例如: 7 0 2 6\n");
printf("请输入访问串: ");
for(i=0;i<512;i++) {
if(scanf("%d", &page[i])!=1) break;
if(getchar()==0x0a && i>0) break;
}
total_pages=i+1; //访问串大小
printf("访问串大小:%d\n访问串为: ", total_pages);
for(i=0;i<total_pages;i++) printf("%d ", page[i]);
printf("\n\n");
}
int main()
{
int frames;
system("color f0");
Input_reference_string();
for(frames=2;frames<=total_pages;frames++){ //从2个页面到total_pages个页面
printf(" 分配%2d个页面时,", frames);
OPT(frames);
//FIFO(frames);
printf("\n");
}
return 0;
}
#Linux# #代码#页面置换算法(FIFO和OPT)
最新推荐文章于 2023-02-25 16:02:06 发布