操作系统之分页管理方式下存储分配情况模拟

借用外存空闲分区管理中位示图的方法来表示主存分配情况,实现主存空间的分配和回收。

实例

  1. 分页式存储器把主存分成大小相等的若干块,作业的信息也按块的大小分页,作业装入主存时可把作业的信息按页分散存放在主存的空闲块中,为了说明主存中哪些块已经被占用,哪些块是尚未分配的空闲块,可用一张位示图来指出。位示图可由若干存储单元来构成,其中每一位与一个物理块对应,用0/1表示对应块为空闲/已占用。
  2. 假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成,另用一单元记录当前空闲块数。如果已有第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了,那么位示图情况如下: 在这里插入图片描述
  3. 当要装入一个作业时,根据作业对主存的需要量,先查当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功。若能满足 ,则查位示图,找出为“0”的一些位,置上占用标志“1”,从“当前空闲块数”中减去本次占用块数。
    按找到的计算出对应的块号,其计算公式为:
    = j × 8 + i 块号= j\times8 + i
    其中,j 表示找到的是第n个字节,i 表示对应的是第n位。
    根据分配给作业的块号,为作业建立一张页表,页表格式: 在这里插入图片描述
  4. 当一个作业执行结束,归还主存时,根据该作业的页表可以知道应归还的块号,由块号可计算出在位示图中的对应位置,把对应位的占用标志清成“0”,表示对应的块已成为空闲块。归还的块数加入到当前空闲块数中。由块号计算在位示图中的位置的公式如下:
    j = [ / 8 ] [ ] i = / 8 字节号 j= [块号/8] ([ ]表示取整)\\ 位数 i = {块号/8} ({ }表示取余)
  5. 设计实现主存分配和回收的程序。
    1). 假定位示图的初始状态如(2)所述,现有一信息量为5页的作业要装入,运行你所设计的分配程序,为作业分配主存且建立页表(格式如(3)所述)。
    2). 然后假定有另一作业执行结束,它占用的块号为第4,5,6和31块,运行你所设计的回收程序,收回作业归还的主存块。

实例代码

结果:
  1. 如上述(2)的初始状态:
    在这里插入图片描述
  2. 一信息量为5页的作业装入,为作业分配主存且建立页表
    在这里插入图片描述该作业执行结束,收回改作业归还的主存块在这里插入图片描述
  3. 假定有另一作业执行结束,它占用的块号为第4,5,6和31块,收回作业归还的主存块在这里插入图片描述
代码:
#include<bits/stdc++.h>
using namespace std;
# define N 8

//假设第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了
int ori[10] = {0,1,4,5,6,9,11,13,24,31}; 
//假定有另一作业执行结束,它占用的块号为第4,5,6和31块,收回作业归还的主存块 
int hui[4] = {4,5,6,31};
int store[N][N] ;//假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成
int sum;//要装入的作业所占的内存块数
int work[64];//分配给作业的块号,为作业建立的页表 
int alloc ;//已分配的内存块数 

////假设第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了 
void init()
{
	//记录已经分配了的主存块数,0/1表示对应块为空闲/已占用
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			store[i][j] = 0;
	//根据 字节号  j=[块号/8]    ([  ]表示取整)
	//		位数  i={块号/8}    ({  }表示取余)
	//更新位示图 
	for(int i=0;i<10;i++)
	{
		int m = ori[i]/N;int n =ori[i]%N;
		store[m][n] = 1;
	}
	//记录已经分配了的主存块数 
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			if(store[i][j] == 1) alloc ++;
	
}
void output()
{
	cout<<"******************位示图情况如下*******************"<<endl<<endl;
	cout<<"已分配块数:"<<alloc<<endl;
	cout<<"            ";
	for(int i=0;i<N;i++) cout<<i<<"  ";cout<<endl;
	for(int i=0;i<N;i++)
	{
		cout<<"         "<<i<<"  ";
		for(int j=0;j<N;j++)
			cout<<store[i][j]<<"  ";
		cout<<endl;
	} 
	cout<<endl;
 } 
// 根据 块号= j*8 + i,为当前作业分配内存块 
void alloc_work(){
	alloc += sum;
	int cnt = 0;
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
		{
			// 查位示图,找出为"0"的一些位,置上占用标志"1"  
			if(store[i][j] == 0){
				store[i][j] = 1;
				work[cnt] = i*8 + j;
				cnt++;
				if(cnt == sum) return;
			}
		 } 
	}
}
void output_work(){
	cout<<endl<<"********************该作业的页表************************* "<<endl<<endl;
 	cout<<"            "<<"页号"<<"      块号"<<endl; 
	for(int i=0;i<sum;i++)
	{
		cout<<"              "<<i<<"        "<<work[i]<<endl;
	}
	cout<<endl;
}
//根据 字节号  j=[块号/8]    ([  ]表示取整)
//		位数  i={块号/8}    ({  }表示取余)
// 根据该作业的页表找到内存块号,回收内存块号 
void re_work(){
	alloc -= sum;
	for(int i=0;i<sum;i++)
	{
		int m = work[i] / 8;
		int n = work[i] % 8;
		store[m][n] = 0;
	}
} 
// 根据特定的作业的页表找到内存块号,回收内存块号 
void re_work2(){
	alloc -= 4;
	for(int i=0;i<sum;i++)
	{
		int m = hui[i] / 8;
		int n = hui[i] % 8;
		store[m][n] = 0;
	}
}

int main()
{
	init();
	output();
	cout<<"请输入要装入的作业所要占的内存块数"<<endl;
	cin>>sum;
	//先查输入是否合理 
	if(sum<0) cout<<"输入错误"<<endl; 
	//当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功 
	else if(sum>(64-alloc)) cout<<"资源数量不够,不能分配"<<endl;
	else{
		alloc_work();
		cout<<"分配成功"<<endl;
		output();
		output_work();
		cout<<"正在作业...................."<<endl; 
		re_work();
		cout<<"回收作业...................."<<endl;
		cout<<"回收完成"<<endl; 
		output();
	}
	cout<<"假定有另一作业执行结束,它占用的块号为第4,5,6和31块,收回作业归还的主存块"<<endl;
	re_work2();
	cout<<"回收作业...................."<<endl;
	cout<<"回收完成"<<endl; 
	output();
	return 0;
}

通用模拟算法(需输入)

结果:
  1. 默认初始状态如实例(2)所示,在这里插入图片描述
  2. 装入作业 在这里插入图片描述
    该作业结束,回收该作业在这里插入图片描述
  3. 回收作业在这里插入图片描述
代码:
#include<bits/stdc++.h>
using namespace std;
# define N 8

//假设第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了
int ori[10] = {0,1,4,5,6,9,11,13,24,31}; 
//假定有另一作业执行结束,它占用的块号为第4,5,6和31块,收回作业归还的主存块 
int hui[4] = {4,5,6,31};
int store[N][N] ;//假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成
int sum;//要装入的作业所占的内存块数
int work[64];//分配给作业的块号,为作业建立的页表 
int alloc ;//已分配的内存块数 

////假设第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了 
void init()
{
	//记录已经分配了的主存块数,0/1表示对应块为空闲/已占用
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			store[i][j] = 0;
	//根据 字节号  j=[块号/8]    ([  ]表示取整)
	//		位数  i={块号/8}    ({  }表示取余)
	//更新位示图 
	for(int i=0;i<10;i++)
	{
		int m = ori[i]/N;int n =ori[i]%N;
		store[m][n] = 1;
	}
	//记录已经分配了的主存块数 
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			if(store[i][j] == 1) alloc ++;
	
}
void output()
{
	cout<<"******************位示图情况如下*******************"<<endl<<endl;
	cout<<"已分配块数:"<<alloc<<endl;
	cout<<"            ";
	for(int i=0;i<N;i++) cout<<i<<"  ";cout<<endl;
	for(int i=0;i<N;i++)
	{
		cout<<"         "<<i<<"  ";
		for(int j=0;j<N;j++)
			cout<<store[i][j]<<"  ";
		cout<<endl;
	} 
	cout<<endl;
 } 
// 根据 块号= j*8 + i,为当前作业分配内存块 
void alloc_work(){
	alloc += sum;
	int cnt = 0;
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
		{
			// 查位示图,找出为"0"的一些位,置上占用标志"1"  
			if(store[i][j] == 0){
				store[i][j] = 1;
				work[cnt] = i*8 + j;
				cnt++;
				if(cnt == sum) return;
			}
		 } 
	}
}
void output_work(){
	cout<<endl<<"********************该作业的页表************************* "<<endl<<endl;
 	cout<<"            "<<"页号"<<"      块号"<<endl; 
	for(int i=0;i<sum;i++)
	{
		cout<<"              "<<i<<"        "<<work[i]<<endl;
	}
	cout<<endl;
}
//根据 字节号  j=[块号/8]    ([  ]表示取整)
//		位数  i={块号/8}    ({  }表示取余)
// 根据该作业的页表找到内存块号,回收内存块号 
void re_work(){
	alloc -= sum;
	for(int i=0;i<sum;i++)
	{
		int m = work[i] / 8;
		int n = work[i] % 8;
		store[m][n] = 0;
	}
} 

int main()
{
	init();
	output();
	int judge = 0;
	while(1)
	{
		cout<<"***************************************************************"<<endl;
		cout<<"          如果装入作业,请输入数字  “1 ”"<<endl;
		cout<<"          如果回收作业,请输入数字  “2 ”"<<endl;
		cout<<"***************************************************************"<<endl;
		cin>> judge;
		if(judge == 1)
		{
			cout<<"请输入要装入的作业所要占的内存块数"<<endl;
			cin>>sum;
			//先查输入是否合理 
			if(sum<0) cout<<"输入错误"<<endl; 
			//当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功 
			else if(sum>(64-alloc)) cout<<"资源数量不够,不能分配"<<endl;
			else{
				alloc_work();
				cout<<"分配成功"<<endl;
				output();
				output_work();
				cout<<"正在作业...................."<<endl; 
				re_work();
				cout<<"回收作业...................."<<endl;
				cout<<"回收完成"<<endl; 
				output();
			} 
		}
		else if(judge == 2)
		{
			cout<<"请输入要回收的作业所要占的内存块数"<<endl;
			cin>>sum;
			//先查输入是否合理 
			if(sum<0) cout<<"输入错误"<<endl; 
			//当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功 
			else if(sum>alloc) cout<<"要回收的资源大于已占用的资源,不能回收"<<endl;
			else{
				cout<<"请输入要回收的资源的块号"<<endl;
				for(int i=0;i<sum;i++) cin>>work[i];   
				re_work();
				cout<<"回收作业...................."<<endl;
				cout<<"回收完成"<<endl; 
				output();
			} 
		}
	}
	return 0;
}
发布了99 篇原创文章 · 获赞 16 · 访问量 9859

猜你喜欢

转载自blog.csdn.net/weixin_42664622/article/details/103770169