操作系统原理与实验——实验十一页面置换

实验指南 

运行环境:

Dev c++

算法思想

本实验是模拟虚拟存储管理方式中的请求分页式技术中的页面置换算法,对于当前访问的页面号如果有对应的内存物理块号则直接访问(必要时可调整物理块中的页面序号),否则先输出缺页访问标志+,然后再判断物理块是否已存满,未满则直接换入当前页,若已满,则先将内存物理块中块首页面号淘汰且换出,然后再将当前页换入。

FIFO是选择在内存驻留时间最长的页面进行置换。

LFU是选择最长时间没有被引用的页面进行置换。

核心数据结构

const int N = 1e3 + 10;

void out()

{

    puts("***********请求分页式存储管理***********");

    puts("\t*\t1.FIFO分配\t*\t");

    puts("\t*\t2.LRU(LFU)分配\t*\t");

    puts("\t*\t0.退出\t*\t");

    printf("\t\t请输入选项:");

}

struct Y

{

    int cnt, val;

    friend bool operator<(Y a, Y b)  //cnt为优先级 val为页面  cnt越大,优先级越高,越优先出队

    {

        return a.cnt < b.cnt;

    }

};

priority_queue< Y, vector<Y> > q;

string s; //作业名

int n, m, ss[N], vis[N], ans[N][N], u[N];

//n为物理块的块数

//m为作业长度

//vis数组用于记录本次是否产生缺页面

//二维数组ans用于记录调度过程中的页面置换情况

//ss[N] 记录需要调度的页面顺序

vector<int> v; //用于存放物理块序列

程序框架

#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;

struct Y

{

    int cnt, val;

    friend bool operator<(Y a, Y b)  //cnt为优先级 val为页面  cnt越大,优先级越高,越优先出队

    {

        return a.cnt < b.cnt;

    }

};

priority_queue< Y, vector<Y> > q;

string s; //作业名

int n, m, ss[N], vis[N], ans[N][N], u[N];

//n为物理块的块数

//m为作业长度

//vis数组用于记录本次是否产生缺页面

//二维数组ans用于记录调度过程中的页面置换情况

//ss[N] 记录需要调度的页面顺序

vector<int> v; //用于存放物理块序列

//函数名:out  参数:无

void out()

{

    //函数功能:输出选择界面菜单,1为FIFO,2为LFU,0退出

}

//函数名:input  参数:无

void input()

{

  //函数功能:输入作业信息

}

//函数名:print    参数:无

void print()

{

   //函数功能:输出页面置换详情和缺页中断率

}

//函数名:solve1   参数:无

void solve1()

{

//函数功能:进行FIFO调度

}

//函数名:solve2   参数:无

void solve2()

{

//函数功能:进行LRU调度

}

int main()

{

    // #ifndef ONLINE_JUDGE

    //     freopen("in.txt", "r", stdin);

    //     freopen("out.txt", "w", stdout);

    // #endif

    printf("请输入物理块的块数:");

    cin >> n;

    out();

    int f;

    cin>>f;

    while (f!=0)

    {

        if (!f)

            break;

        input();

        memset(ans, -1, sizeof ans);

        memset(vis, 0, sizeof vis);

        memset(u, -1, sizeof u);

        if (f == 1)

        {

            solve1();

            print();

        }

        else

        {

            solve2();

            print();

        }

        out();

        cin>>f;

    }

    return 0;

}

测试用例:

3

1

jobA

20

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

2

jobB

20

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

0

4

1

JobC

20

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

2

jobD

20

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

0

关键代码

#include<stdio.h> 
const int N = 1e3 + 10;
char s[20]; //作业名
int n, m, u[N], vis[N], ans[N][N], ss[N];
//n为物理块的块数
//m为作业长度
//u数组记录被调出的页面 
//vis数组用于记录本次是否产生缺页面(1表示缺页,0表示不缺页)
//二维数组ans用于记录调度过程中的页面置换情况
//ss[N] 记录需要调度的页面顺序

//函数名:out  参数:无
void out()
{
    //函数功能:输出选择界面菜单,1为FIFO,2为LFU,0退出
    printf("***********请求分页式存储管理***********\n");
    printf("\t*\t1.FIFO分配\t*\t\n");
    printf("\t*\t2.LRU(LFU)分配\t*\t\n");
    printf("\t*\t0.退出\t*\t\n");
    printf("\t\t请输入选项:\n");
}
//函数名:input  参数:无
void input()
{
  //函数功能:输入作业信息
  printf("请输入作业名:");
  scanf("%s",&s);
  printf("请输入作业页面长度:");
  scanf("%d",&m);
  printf("请输入作业页面顺序:\n");
  for(int i = 0;i<m;i++)
  scanf("%d",&ss[i]);
}
//函数名:print    参数:无
void print()
{
   //函数功能:输出页面置换详情和缺页中断率
   int count = 0;
   printf("作业名:%s\n作业调度过程:\n",s); 
   printf("\t");
   for(int i=0;i<m;i++)
   {
   		printf("%2d ",i);
   }
   printf("\n\t");
   for(int i=0;i<m;i++)
   {
   		printf("%2d ",ss[i]);
   }
   for(int i=0;i<n;i++)
   {
   		for(int j=0;j<m;j++)
   		{
   			if(j==0)
   			{
   				printf("\n%d\t ",i); 
			}
			if(ans[i][j]!=-1)
			{
				printf("%d  ",ans[i][j]);
			}
			else
			{
				printf("   ");
			}
		}
   }
   printf("\n\t ");
   for(int i=0;i<m;i++)
   {
   		if(vis[i] == 1)
   		{
   			printf("+  ");
   			count++;//
		}
   		else
   		{
   			printf("   ");
		}
   }
   printf("\n\t ");
   for(int i=0;i<m;i++)
   {
   		if(u[i] != -1)
   		{
   			printf("%d  ",u[i]);
		}
   		else
   		{
   			printf("   ");
		}
   }
   printf("\n缺页中断率为:%.2f\n",count*1.0/m*100);
}
//函数名:solve1   参数:无
void solve1() 
{
//函数功能:进行FIFO调度
	printf("**********打印作业FIFO调度进入主存页的过程**********\n");
	for(int i=0;i<m;i++)
	{
		int flag = 0;//表示前一列是否有相同页面 
		for(int k = 0;k<n;k++)
		{
			if(i>=1&&ans[k][i-1] !=-1&&ans[k][i-1] == ss[i])
			{
				flag = 1;
				break;
			}
		}
		if(flag == 1)//内存里调入了当前要调入的页面
		{
			for(int j = 0;j<n;j++)
			{
				ans[j][i] = ans[j][i-1];
			}
		}
		else//内存里没有调入了当前要调入的页面
		{
			int j = 0;
			if(i>=1&&ans[n-1][i-1]!=-1)
			{
				u[i] = ans[n-1][i-1];
			}
			for(j = n-1;j>0&&i>=1;j--)
			{
				ans[j][i] = ans[j-1][i-1];
			} 
			ans[0][i] = ss[i];
			vis[i] = 1;
		}
	}
}
//函数名:solve2   参数:无
void solve2() 
{
//函数功能:进行LRU调度
	printf("**********打印作业LUR调度进入主存页的过程**********\n");
	for(int i = 0;i<m;i++)
	{
		int flag = 0,k,j;//表示这一列是否有相同页面 
		for(k = 0;k<n;k++)
		{
			if(ans[k][i-1] !=-1&&ans[k][i-1] == ss[i])
			{
				flag = 1;
				break;
			}
		}
		if(flag == 1)//内存里调入了当前要调入的页面
		{
			j = n-1;
			while(j!=k)
			{
				ans[j][i] = ans[j][i-1];
				j--;
			}
			for(;j>=0;j--)
			{
				ans[j][i] = ans[j-1][i-1];
			}
			ans[0][i] = ss[i];
		}
		else//内存里没有调入了当前要调入的页面 
		{
			int j = 0;
			if(i>=1&&ans[n-1][i-1]!=-1)
			{
				u[i] = ans[n-1][i-1];
			}
			for(j = n-1;j>0&&i>=1;j--)
			{
				ans[j][i] = ans[j-1][i-1];
			} 
			ans[0][i] = ss[i];
			vis[i] = 1;
		}	
	}
}

int main()
{
    printf("请输入物理块的块数:");
    scanf("%d",&n);
    out();
    int f;
    scanf("%d",&f);
    while (f!=0)
    {
        if (!f)
            break;
        input();
        for(int i = 0;i<N;i++)
        {
        	for(int j = 0;j<N;j++)
        	{
        		ans[i][j] = -1;
			}
			vis[i] = 0;
			u[i] = -1;
		}
        if (f == 1)
        {
            solve1();
            print();
        }
        else
        {
            solve2();
            print();
        }
        out();
        scanf("%d",&f);
    }

    return 0;
}

运行结果

实验总结

①学会了consta和define的区别;

②没有考虑到如果没有对页面置换情况数组怎么输出的问题,导致一直在算法查错;

③更加深入了解了二维数组按列存储的思想;

④保证程序的简洁性就要找到程序处理时用的方法哪里是相同的可以将其合并;

⑤还是对选择结构的条件没有把握得特别好,得多加练习。

tips:本题思想

  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值