/*****************************************************************
* *
* 操作系统实验四 页面置换模拟 *
* 2009.11.11 *
******************************************************************/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <windows.h>
#define M 3
#define N 8
using namespace std;
/********************************************
类pageAllot声明、定义与其成员函数实现
*********************************************/
class pageAllot//页面分配表
{
public:
int m_Allot_pageNum[M];
int m_Allot_pageState[M];//保存已经分配在分配页面里的页号
public:
void mb_init_setData();//初始化数据
void mb_setData(int Allot_pageNum,int pageNum);//分配内存给访问页
void mb_prtPageAllot(pageAllot &pageAllot_1);//打印输出页面分配表
};
/*------------------------------------------------------*/
void pageAllot::mb_init_setData()
{
for(int i=0; i<M; ++i)
{
m_Allot_pageNum[i] = i;
m_Allot_pageState[i] = -1;
}
}
/*------------------------------------------------------*/
void pageAllot::mb_setData(int Allot_pageNum, int pageNum)//pageNum是需要访问的页号
{
m_Allot_pageState[Allot_pageNum] = pageNum;
}
/*------------------------------------------------------*/
void pageAllot::mb_prtPageAllot(pageAllot &pageAllot_1)
{
cout<<"页面分配表"<<endl;
cout<<"|***********************|"<<endl;
cout<<"| 页面分配号 | 分配状态 |"<<endl;
for (int i=0; i<M; ++i)
{
cout<<"|"<<setw(6)<<pageAllot_1.m_Allot_pageNum[i]<<setw(7)
<<"|"<<setw(5)<<pageAllot_1.m_Allot_pageState[i]<<setw(6)<<"|"<<endl;
}
cout<<"|***********************|"<<endl;
}
/*------------------------------------------------------*/
/********************************************
类pageForm的声明、定义与其成员函数实现
*********************************************/
class pageForm
{
public:
int m_pageNum[N];//页号
int m_pageAllotNum[N];//分配页号
int m_memoryState[N];//是否在内存里
int m_vistCount[N];//访问次数
char m_noPage[N];//缺页状态
int m_temp[100];//保存被置换的页号记录
public:
void mb_init_setData();
int mb_replaceData(int pageNum, int min_pageNum, int s);
void mb_vist_setData(int min_pageNum, int pageAllotNum);
void mb_prtPageForm(pageForm &pageForm_1);
int mb_Min(pageForm &pageForm_1, pageAllot &pageAllot_1);
int mb_checkPage(pageForm &pageForm_1, pageAllot &pageAllot_1, int pageNum, int temp);
};
/*------------------------------------------------------*/
void pageForm::mb_init_setData()
{
for (int i=0; i<N; ++i)
{
m_pageNum[i] = i;
m_pageAllotNum[i] = -1;
m_memoryState[i] = 0;
m_vistCount[i] = 0;
m_noPage[i] = '-';
m_temp[i] = -1;
}
}
/*------------------------------------------------------*/
void pageForm::mb_vist_setData(int pageNum, int pageAllotNum)
{
m_pageAllotNum[pageNum] = pageAllotNum;
m_memoryState[pageNum] = 1;
m_vistCount[pageNum]++;
}
/*------------------------------------------------------*/
int pageForm::mb_replaceData(int pageNum, int min_pageNum, int s)
{
for (int i=0; i<N; ++i)//所有页的访问次数置0
m_vistCount[i] = 0;
m_temp[s] = min_pageNum;
s++;//通过s的自增来记录页面调出流
m_temp[pageNum] = min_pageNum;
m_pageAllotNum[pageNum] = m_pageAllotNum[min_pageNum];
//将被置换的分配页号赋给当前访问的分配页号
m_vistCount[pageNum]++;
m_pageAllotNum[min_pageNum] = -1;
m_memoryState[min_pageNum] = 0;
return s;//把当前参数s的值返回给全局变量s
}
/*------------------------------------------------------*/
void pageForm::mb_prtPageForm(pageForm &pageForm_1)
{
cout<<"页表"<<endl;
cout<<"|**************************************************************|"<<endl;
cout<<"| 页号 | 页分配号 | 内否 | 访问数 | 缺页 | 置换 | "<<endl;
for (int i=0; i<N; ++i)
{
cout<<"|"<<setw(5)<<pageForm_1.m_pageNum[i]<<setw(5)
<<"|"<<setw(7)<<pageForm_1.m_pageAllotNum[i]<<setw(8)<<"|"
<<setw(5)<<pageForm_1.m_memoryState[i]<<setw(4)<<"|"
<<setw(6)<<pageForm_1.m_vistCount[i]<<setw(5)<<"|"<<setw(5)
<<pageForm_1.m_noPage[i]<<setw(4)<<"|"<<setw(5)
<<pageForm_1.m_temp[i]<<setw(4)<<"|"<<endl;
}
cout<<"|**************************************************************|"<<endl;
}
/*-----------------------求能够被置换的页号----------------------*/
int pageForm::mb_Min(pageForm &pageForm_1, pageAllot &pageAllot_1)
{
int t[M], j = 0;//t[M]用来保存在内存里的三个页号
for (int i=0; i<N; ++i)
{
if (pageForm_1.m_memoryState[i] != 0)
{
t[j] = i;
j++;
}
}
int min = pageForm_1.m_vistCount[t[2]];//min的初值为在内存里的随便一个页的访问量
int index = t[2];//index的初值为min对应的页号,最后这个index是我们需要的返回值
for(int k = 0 ; k < 3 ; k ++)
{
if(min > pageForm_1.m_vistCount[t[k]])
{
min = pageForm_1.m_vistCount[t[k]];
index = t[k];
}
else
if(min == pageForm_1.m_vistCount[t[k]])
index = index > t[k]?t[k]:index;
}
return index;
}
/*------------------------------------------------------------------------*/
//此函数用来返回缺页状态
int pageForm::mb_checkPage(pageForm &pageForm_1, pageAllot &pageAllot_1, int pageNum, int temp)
{
for (int i=0; i<M; ++i)
{
if (pageNum == pageAllot_1.m_Allot_pageState[i])
{
pageForm_1.m_noPage[pageNum] = 'N';//N表示不缺页
break;
}
if (i==2)
{
pageForm_1.m_noPage[pageNum] = 'Y';//Y表示缺页
temp++;//计算缺页数
}
}
return temp;//返回缺页数
}
/*--------------------------------------------------------------------*/
/**********全局变量及对象的定义**********/
pageForm pageForm_1;
pageAllot pageAllot_1;
int s = 10;//s是一个下标用来让m_temp[s]数组保存页面调出流
int temp = 0;//temp用来返回并记录缺页总数
/****************************************************
main函数
*****************************************************/
int main(int argc, char* argv[])
{
pageAllot_1.mb_init_setData();
pageForm_1.mb_init_setData();
system("cls");
pageAllot_1.mb_prtPageAllot(pageAllot_1);
pageForm_1.mb_prtPageForm(pageForm_1);
char array[21];//字符型数组最后一位是保存空的数据。所以要多出一位。
int pageNum;
ifstream fin("a.txt");
fin.getline(array,21);
for (int u=0; u<20; ++u)
{
while (pageNum = array[u]-48)
{
if ( N<pageNum || pageNum<0)
{
cout<<"读入数据无效,请检查您的文件数据是否被破坏或没有数据。"<<endl;
return 0;
}
else
break;
}
Sleep(10000);
for (int i=0; i<M; ++i)
{
if (pageAllot_1.m_Allot_pageState[i] == -1)
{
temp = pageForm_1.mb_checkPage(pageForm_1, pageAllot_1, pageNum, temp);
pageAllot_1.mb_setData(i, pageNum);
pageForm_1.mb_vist_setData(pageNum, i);
system("cls");
pageAllot_1.mb_prtPageAllot(pageAllot_1);
pageForm_1.mb_prtPageForm(pageForm_1);
break;
}
if (pageForm_1.m_memoryState[pageNum] == 1)
{
temp = pageForm_1.mb_checkPage(pageForm_1, pageAllot_1, pageNum, temp);
if (pageForm_1.m_pageNum[pageNum] == pageNum)
{pageForm_1.m_vistCount[pageNum]++;
system("cls");
pageAllot_1.mb_prtPageAllot(pageAllot_1);
pageForm_1.mb_prtPageForm(pageForm_1);
break;}
}
if (i == M-1)
{
int x = pageForm_1.mb_Min(pageForm_1, pageAllot_1);
if (x>=0)
{
temp = pageForm_1.mb_checkPage(pageForm_1, pageAllot_1, pageNum, temp);
pageAllot_1.mb_setData(pageForm_1.m_pageAllotNum[x], pageNum);
pageForm_1.mb_vist_setData(pageNum, x);
s = pageForm_1.mb_replaceData(pageNum, x, s); //s获得更新值
system("cls");
pageAllot_1.mb_prtPageAllot(pageAllot_1);
pageForm_1.mb_prtPageForm(pageForm_1);
break;
}
}
}
}
cout<<endl;
cout<<"*****************不经常使用页面置换算法(LFU)模拟*********************"<<endl;
cout<<"读入的访问串是:";
for (int j=0; j<20; ++j)
cout<<setw(2)<<array[j]-48;
cout<<endl;
cout<<"---------------------------------------------------------------------"<<endl;
cout<<"最不经常使用页面置换算法(LFU) 页面调出流:";
for (int i=10; i<s; ++i)
{
cout<<setw(2)<<pageForm_1.m_temp[i];
}
cout<<endl;
cout<<"共缺页数:"<<temp<<endl;
return 0;
}
/***********************************************************************/