代码
//
初始化界面框架
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0 ) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000 );
CMenu * pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if ( ! strAboutMenu.IsEmpty())
{
pSysMenu -> AppendMenu(MF_SEPARATOR);
pSysMenu -> AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
address = new int [ 300 ];
m_list.InsertColumn( 0 , " 页面大小 " );
m_list.InsertColumn( 1 , " 内存块数 " );
m_list.InsertColumn( 2 , " 算法 " );
m_list.InsertColumn( 3 , " 缺页中断率 " );
CRect rect;
GetClientRect( & rect);
int len = rect.right - rect.left + 4 ;
for ( int i = 0 ; i < 4 ; i ++ )
m_list.SetColumnWidth(i,len / 4 );
return TRUE; // return TRUE unless you set the focus to a control
}
//
// 根据所选择的条件进行页面调度
void CMyDlg::OnRun()
{
// TODO: Add your control notification handler code here
int d[ 300 ];
int i;
d[ 0 ] = 10000 ;
srand( (unsigned)time( NULL ) );
for (i = 1 ; i < 256 ; i ++ ) { // 随机产生地址流
int r = rand() % 1024 + 1 ;
if (r >= 1 && r <= 512 )
d[i] = d[i - 1 ] + 1 ;
else if (r >= 513 && r <= 768 )
d[i] = rand() % d[i - 1 ] + 1 ;
else {
int a = (rand() % 32767 + d[i - 1 ]) % 32767 + 1 ;
d[i] = a;
}
}
UpdateData( 1 );
if (m_page < 0 || m_page > 4 )
{
MessageBox( " 请选择页面 " );
return ;
}
int p;
switch (m_page)
{
case 0 :
p = 1 ;
break ;
case 1 :
p = 16 ;
break ;
case 2 :
p = 2 ;
break ;
case 3 :
p = 4 ;
break ;
case 4 :
p = 8 ;
break ;
}
m_max = 0 ; // 页面数;
m_cnt = 0 ; // 地址页号
// 按照页面大小将指令地址转化为页号。对于相邻相同的页号,合并为一个。
address[ 0 ] = d[ 0 ] / (p * 1024 );
for (i = 1 ; i < 256 ; i ++ )
{
int tmp = d[i] / (p * 1024 );
if (tmp != address[m_cnt])
address[ ++ m_cnt] = tmp;
if (m_max < tmp)
m_max = tmp;
}
Update();
}
//
// 根据所选择的算法,显示页面置换效率
void CMyDlg::Update()
{
bool f[ 40 ];
int i,j,k;
m_list.DeleteAllItems();
CString str;
int p;
switch (m_page)
{
case 0 :
p = 1 ;
break ;
case 1 :
p = 16 ;
break ;
case 2 :
p = 2 ;
break ;
case 3 :
p = 4 ;
break ;
case 4 :
p = 8 ;
break ;
}
int row = 0 ;
queue < int > qu;
while ( ! qu.empty())
qu.pop();
// 先进先出置换算法。该算法总是淘汰最先进入内存的页面,
// 也就是选择在内存中驻留时间最久的页面予以淘汰。
if (m_algorithm == " FIFO " )
{
// MessageBox("FIFO");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
for (k = 0 ; k < m_cnt ; k ++ ) // 进程地址号
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 先进先出
{
int tmp = qu.front();
qu.pop();
f[tmp] = 0 ;
qu.push(address[k]);
f[address[k]] = 1 ;
}
else { // 内存块未满
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
// 最近最久未使用置换算法。该算法赋予每个页面一个访问字段,
// 用来记录一个页面自上次被访问以来所经历的时间T,
// 当须淘汰一个页面时,选择现有页面中其T值最大的给予淘汰。
else if (m_algorithm == " LRU " )
{
// MessageBox("LRU");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
int time[ 50 ] = { 0 }; // 记录时间
queue < int > qutmp;
for (k = 0 ; k < m_cnt ; k ++ )
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 选择最近最久未使用
{
int tmp = - 1 ;
int d;
for (j = 0 ; j < 50 ; j ++ ) {
if (tmp < time[j]) {
tmp = time[j];
d = j;
}
}
while ( ! qu.empty())
{
int tmp = qu.front();
qu.pop();
if (tmp == d)
{
f[tmp] = 0 ;
time[d] = 0 ;
}
else {
qutmp.push(tmp);
time[tmp] ++ ;
}
}
while ( ! qutmp.empty())
{
qu.push(qutmp.front());
qutmp.pop();
}
qu.push(address[k]);
f[address[k]] = 1 ;
time[address[k]] = 1 ;
}
else { // 内存块未满
while ( ! qu.empty())
{
int tmp = qu.front();
qu.pop();
time[tmp] ++ ;
qutmp.push(tmp);
}
while ( ! qutmp.empty())
{
qu.push(qutmp.front());
qutmp.pop();
}
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
time[address[k]] = 1 ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
// 最佳淘汰算法。其所选择的被淘汰页面,将是以后永不使用的,
// 或是在最长(未来)时间内不再被访问的页面。
else if (m_algorithm == " OPT " )
{
// MessageBox("OPT");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
queue < int > q;
int opt[ 50 ] = { 0 };
int mm; // 定义理想型最佳淘汰算法的值
for (k = 0 ; k < m_cnt ; k ++ ) // 进程地址号
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 最近最久未使用
{
int tmp,d;
mm = 0 ;
while ( ! qu.empty())
{
tmp = qu.front();
qu.pop();
for (j = k + 1 ; j < m_cnt ; j ++ ) {
if (address[j] == tmp)
break ;
}
if (j == m_cnt)
opt[tmp] = 50 ;
else opt[tmp] = j;
q.push(tmp);
if (mm < opt[tmp]) {
mm = opt[tmp];
d = tmp;
}
}
while ( ! q.empty())
{
tmp = q.front();
q.pop();
if (tmp == d) {
f[tmp] = 0 ;
}
else qu.push(tmp);
}
qu.push(address[k]);
f[address[k]] = 1 ;
}
else { // 内存块未满
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
else
{
MessageBox( " 请选择页面算法 " );
return ;
}
}
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0 ) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000 );
CMenu * pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if ( ! strAboutMenu.IsEmpty())
{
pSysMenu -> AppendMenu(MF_SEPARATOR);
pSysMenu -> AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
address = new int [ 300 ];
m_list.InsertColumn( 0 , " 页面大小 " );
m_list.InsertColumn( 1 , " 内存块数 " );
m_list.InsertColumn( 2 , " 算法 " );
m_list.InsertColumn( 3 , " 缺页中断率 " );
CRect rect;
GetClientRect( & rect);
int len = rect.right - rect.left + 4 ;
for ( int i = 0 ; i < 4 ; i ++ )
m_list.SetColumnWidth(i,len / 4 );
return TRUE; // return TRUE unless you set the focus to a control
}
//
// 根据所选择的条件进行页面调度
void CMyDlg::OnRun()
{
// TODO: Add your control notification handler code here
int d[ 300 ];
int i;
d[ 0 ] = 10000 ;
srand( (unsigned)time( NULL ) );
for (i = 1 ; i < 256 ; i ++ ) { // 随机产生地址流
int r = rand() % 1024 + 1 ;
if (r >= 1 && r <= 512 )
d[i] = d[i - 1 ] + 1 ;
else if (r >= 513 && r <= 768 )
d[i] = rand() % d[i - 1 ] + 1 ;
else {
int a = (rand() % 32767 + d[i - 1 ]) % 32767 + 1 ;
d[i] = a;
}
}
UpdateData( 1 );
if (m_page < 0 || m_page > 4 )
{
MessageBox( " 请选择页面 " );
return ;
}
int p;
switch (m_page)
{
case 0 :
p = 1 ;
break ;
case 1 :
p = 16 ;
break ;
case 2 :
p = 2 ;
break ;
case 3 :
p = 4 ;
break ;
case 4 :
p = 8 ;
break ;
}
m_max = 0 ; // 页面数;
m_cnt = 0 ; // 地址页号
// 按照页面大小将指令地址转化为页号。对于相邻相同的页号,合并为一个。
address[ 0 ] = d[ 0 ] / (p * 1024 );
for (i = 1 ; i < 256 ; i ++ )
{
int tmp = d[i] / (p * 1024 );
if (tmp != address[m_cnt])
address[ ++ m_cnt] = tmp;
if (m_max < tmp)
m_max = tmp;
}
Update();
}
//
// 根据所选择的算法,显示页面置换效率
void CMyDlg::Update()
{
bool f[ 40 ];
int i,j,k;
m_list.DeleteAllItems();
CString str;
int p;
switch (m_page)
{
case 0 :
p = 1 ;
break ;
case 1 :
p = 16 ;
break ;
case 2 :
p = 2 ;
break ;
case 3 :
p = 4 ;
break ;
case 4 :
p = 8 ;
break ;
}
int row = 0 ;
queue < int > qu;
while ( ! qu.empty())
qu.pop();
// 先进先出置换算法。该算法总是淘汰最先进入内存的页面,
// 也就是选择在内存中驻留时间最久的页面予以淘汰。
if (m_algorithm == " FIFO " )
{
// MessageBox("FIFO");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
for (k = 0 ; k < m_cnt ; k ++ ) // 进程地址号
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 先进先出
{
int tmp = qu.front();
qu.pop();
f[tmp] = 0 ;
qu.push(address[k]);
f[address[k]] = 1 ;
}
else { // 内存块未满
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
// 最近最久未使用置换算法。该算法赋予每个页面一个访问字段,
// 用来记录一个页面自上次被访问以来所经历的时间T,
// 当须淘汰一个页面时,选择现有页面中其T值最大的给予淘汰。
else if (m_algorithm == " LRU " )
{
// MessageBox("LRU");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
int time[ 50 ] = { 0 }; // 记录时间
queue < int > qutmp;
for (k = 0 ; k < m_cnt ; k ++ )
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 选择最近最久未使用
{
int tmp = - 1 ;
int d;
for (j = 0 ; j < 50 ; j ++ ) {
if (tmp < time[j]) {
tmp = time[j];
d = j;
}
}
while ( ! qu.empty())
{
int tmp = qu.front();
qu.pop();
if (tmp == d)
{
f[tmp] = 0 ;
time[d] = 0 ;
}
else {
qutmp.push(tmp);
time[tmp] ++ ;
}
}
while ( ! qutmp.empty())
{
qu.push(qutmp.front());
qutmp.pop();
}
qu.push(address[k]);
f[address[k]] = 1 ;
time[address[k]] = 1 ;
}
else { // 内存块未满
while ( ! qu.empty())
{
int tmp = qu.front();
qu.pop();
time[tmp] ++ ;
qutmp.push(tmp);
}
while ( ! qutmp.empty())
{
qu.push(qutmp.front());
qutmp.pop();
}
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
time[address[k]] = 1 ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
// 最佳淘汰算法。其所选择的被淘汰页面,将是以后永不使用的,
// 或是在最长(未来)时间内不再被访问的页面。
else if (m_algorithm == " OPT " )
{
// MessageBox("OPT");
for (i = 0 ; i <= m_max ; i ++ ) // 内存块数
{
memset(f, 0 , sizeof (f));
int m = 0 ;
int num = 0 ;
queue < int > q;
int opt[ 50 ] = { 0 };
int mm; // 定义理想型最佳淘汰算法的值
for (k = 0 ; k < m_cnt ; k ++ ) // 进程地址号
{
if (f[address[k]] == 1 ) continue ; // 已经存在;
if (num == i + 1 ) // 最近最久未使用
{
int tmp,d;
mm = 0 ;
while ( ! qu.empty())
{
tmp = qu.front();
qu.pop();
for (j = k + 1 ; j < m_cnt ; j ++ ) {
if (address[j] == tmp)
break ;
}
if (j == m_cnt)
opt[tmp] = 50 ;
else opt[tmp] = j;
q.push(tmp);
if (mm < opt[tmp]) {
mm = opt[tmp];
d = tmp;
}
}
while ( ! q.empty())
{
tmp = q.front();
q.pop();
if (tmp == d) {
f[tmp] = 0 ;
}
else qu.push(tmp);
}
qu.push(address[k]);
f[address[k]] = 1 ;
}
else { // 内存块未满
qu.push(address[k]);
f[address[k]] = 1 ;
num ++ ;
}
m ++ ;
}
double ans = m * 1.0 / m_cnt;
str.Format( " %d " ,p);
m_list.InsertItem(row,str);
str.Format( " %d " ,i + 1 );
m_list.SetItemText(row, 1 ,str);
m_list.SetItemText(row, 2 ,m_algorithm);
str.Format( " %.2f " ,ans * 100 );
str = str + " % " ;
m_list.SetItemText(row, 3 ,str);
row ++ ;
}
}
else
{
MessageBox( " 请选择页面算法 " );
return ;
}
}