/*******************************************************************/
//请分别用FIFO、OPT算法实现“页面置换”的模拟。模拟程序的要求如下:
//
//输入:页面流文件,其中存储的是一系列页面号,用来模拟待换入的页面。
//
//输出:对于每一个页面流文件,标出所使用的算法,
//并且:每换入一个页面(即:每读入一个页面号),判断是否有页面需要被换出。
//若有,把被换出的页面号输出到屏幕;若没有,则要在输出中用特殊标记说明。
//
//初始条件:采用三个页框,初始时均为空。
//
//测试说明:测试教师将事先准备好一组文件,
//从中为每个程序随机指定一至三个作为输入文件
//(被测试者需从键盘输入指定文件的文件名),并查看程序输出结果。
//测试用例:书上p119页,在本地盘建立一个test.txt文件,内容为例中的页面号
//例如:test文本内容为:
// 4 3 2 1 4 3 5 4 3 2 1 5jjjjjjjjj
// kkkk
// jklilkjjj
/******************************************************************/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "iostream.h"
#include <conio.h> /* getch() */
#include <windows.h>
/* 建议还是用宏函数,这样效率更好点,还写成函数的话,调用会增加额外的栈开销 */
/* WINDEF.H 中也定义了,这里最好用宏判断一下 */
#ifndef max
#define max(a,b) do\
{\
return a>b?a:b;\
} while (0);
#endif //max
#define MAX_PAGE 100 //定义最大页数
#define MAX_PAGE_BLOCK 3 //定义最大页面块数
void ShowLog()
{
cout << "**********************************************" << endl;
cout << "* 用FIFO、OPT算法实现“页面置换”的模拟 *" << endl;
cout << "* Copyright 2011/11/19, zww0815@qq.com *" << endl;
cout << "* All Rights Reserved *" << endl;
cout << "**********************************************" << endl;
}
/* 先进先出算法(First in first out) */
void FIFO(int page[],int n)
{
int mem[MAX_PAGE_BLOCK];
int flag = 0;
int i,j;
int d=0;
int count = 0;//缺页中断计数
int count_mz = 0;//命中计数
memset(mem,0,MAX_PAGE_BLOCK*sizeof(int));
cout<<endl<<"# 代表命中"<<" "<<"!后跟的数字代表被换出的页"<<endl;
cout<<endl<<"FIFO算法:"<<endl;
// mem[2]=page[0];
// mem[1]=page[1];
// mem[0]=page[2];
// cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<endl;
for(i = 0; i<n; i++)
{
flag = 0;
//判断有木有命中,命中标志置1
for(j = 0; j<MAX_PAGE_BLOCK; j++)
{
if(mem[j] == page[i])
{
flag = 1;
count_mz++;
break;//如果命中第一个,后面就不要去比较了,后面直接唤出就可以了
}
}
//flag为1表示命中,输出#
if(flag)
{
//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" #" << " ------->命中" << page[i] <<endl;
//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" #"<<endl;
for (int x=0;x<MAX_PAGE_BLOCK;x++)
{
cout << mem[x] << " ";
}
cout << " #" << "=======>命中" << page[i] <<endl;
}
else
{
count++;
int n=MAX_PAGE_BLOCK-1;
d = mem[n];
for (;n>0;n--)
{
mem[n] =mem[n-1];
}
mem[0]=page[i];
for (int x=0;x<MAX_PAGE_BLOCK;x++)
{
cout << mem[x] << " ";
}
cout << " !------->缺页中断,唤出" <<d<<endl;
}
}
cout<<endl<<"共产生缺页中断:"<<count<<"次,"<<"共命中:"<< count_mz <<"次!"<<endl;
};
/* 最优离线算法OPT(OPTimal replacement algorithm) */
void OPT(int page[],int n)
{
int mem[3]={0,0,0};
int flag = 0;
int i,j,s;
int d=0;
int count = 0;//缺页中断计数
int count_mz = 0;//命中计数
int c0=99;
int c1=99;
int c2=99;
cout<<endl<<"# 代表命中"<<" "<<"!后跟的数字代表被换出的页"<<endl;
cout<<endl<<"OPT算法:"<<endl;
mem[2]=page[0];
mem[1]=page[1];
mem[0]=page[2];
cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<endl;
for(i = 3; i<n; i++)
{
flag = 0;
//在三个页面中查找
for(j = 0; j<MAX_PAGE_BLOCK; j++)
{
//命中,标志置1,命中计数自加1
if(mem[j] == page[i])
{
flag = 1;
count_mz++;
break;//如果命中第一个,后面就不要去比较了,后面直接唤出就可以了
}
}
if(flag)
{
int x = 0;
//cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" #"<<endl;
for (;x<MAX_PAGE_BLOCK;x++)
{
cout << mem[x] << " ";
}
cout << " #" << "------->" << page[i] <<"进入页面[" << j << "],命中" <<endl;
}
else
{
for(s = i+1; s<n; s++)
{
if (mem[0] == page[s])
{
c0 = s;
}
else
{
if(mem[1] == page[s])
{
c1 = s;
}
else
{
if(mem[2] == page[s])
{
c2 =s;
}
else if(c0!=99 && c1!=99 && c2!=99)
{
break;
}
}
}
}
// cout<<endl<<c0<<c1<<c2<<" ";
if (c0 >= c1 && c0 >= c2)
{
d = mem[0];
mem[0] = page[i];
cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" !" <<d << "------->" << page[i] << "进入页面[0],唤出" << d <<endl;
}
else if (c1 >= c0 && c1 >= c2)
{
d = mem[1];
mem[1] = page[i];
cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" !" << d << "------->" << page[i] << "进入页面[1],唤出" << d << endl;
}
else
{
d = mem[2];
mem[2] = page[i];
cout<<mem[0]<<' '<<mem[1]<<' '<<mem[2]<<" !" << d << "------->" << page[i] << "进入页面[2],唤出" << d << endl;
}
count++;
c0 = c1 = c2 = 99;
}
}
cout<<endl<<"共产生缺页中断:"<<count+3<<"次,"<<"共命中:"<< count_mz <<"次!"<<endl;
};
int main()
{
FILE *fp;
char pt;
char strFile[10];
char str[10];
int i = 0;
int j = 0;
int page[MAX_PAGE];
int flag = 1;
memset(str,0,sizeof(char)*10);
memset(page,0,sizeof(int)*50);
for(i=0; i<50; i++)
{
page[i] = -1;
}
do
{
ShowLog();
/* 题目要求读入文件路径,打开时有小错误,改成指定文件名方式 */
//cout<<"请输入需要读入文件的路径:" << endl;
/* 获取输入的文件名 */
//gets(strFile);
strcpy(strFile,"test.txt");
//cout << "|" << str << sizeof(str) << strlen(str) << "|" << endl;
/* 文件名不能为空 */
if ( 0 == strlen(strFile))
{
cout << "亲,输入不能为空!" << endl;
Sleep(1000);//暂停1秒
system("cls");//清屏
continue;//下面的就不执行了,继续下一轮循环
}
/* 可读写方式打开文件,该文件必须存在 */
fp = fopen(strFile,"r+");
if(fp==NULL)
{
cout << endl<<"找不到该文件" << endl << "<Enter to continue.>" <<endl;
getch();//暂停,直到接收到任何输入为止
system("cls");
}
else
{
cout << "打开文件" << strFile
<< "成功." << endl;
break;//退出本循环
}
} while (1);
/* 从文件中读取字符 */
cout << "读入page[MAX_PAGE]:" << endl;
/* 这里设置一下最多只读100个数据 */
while((pt = fgetc(fp)) != EOF && j < MAX_PAGE )
{
//i = 0;
if (pt == '\n') continue;//换行符
if (pt == ' ') continue;//空格
if (pt == ' ') continue;//Tab
if(pt>='0' && pt<='9')
{
str[0] = pt;
//i++;
flag = 1;
str[1] = '\0';
page[j] = atoi(str);
//cout<< " page[" << j << "]=" << page[j++];
printf(" page[%d]=%d",j,page[j]);
j++;
if ( 0 == j%5)
{
cout << endl;
}
}
}
cout<< endl << "共读入数字数:" << " j= " << j<<endl;
i = 0;
cout << "从文件中读出的数字依次为:" << endl;
while(i < j )
{
cout<<" page["<< i << "]= "<<page[i];
if ( 0 == (++i)%5 )
{
cout << endl;
}
}
FIFO(page,j);
OPT(page,j);
return 0;
}
模拟页面调度算法——1
最新推荐文章于 2021-05-25 10:14:09 发布