NJUPT南邮 | 操作系统_实验一 页面置换算法

通过实现页面置换的四种算法,理解虚拟存储器的概念、实现方法,页面分配的总体原则、进程运行时系统是怎样选择换出页面的,并分析四种不同的算法各自的优缺点是哪些。
以下算法都要实现:

  1. 最佳置换算法(OPT):将以后永不使用的或许是在最长(未来)时间内不再被访问的页面换出。
  2. 先进先出算法(FIFO):淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
  3. 最近最久未使用算法(LRU):淘汰最近最久未被使用的页面。
  4. 最不经常使用算法(LFU)
#include
#include
#include

typedef struct item
{
	int num;		//页号
	int time;		//LRU算法的等待时间
}Pro;

int pageNum;		//系统分配给作业的主存中的页面数
int memoryNum;		//可用内存页面数

void print(Pro* page1);		//打印当前主存中的页面
int  Search(int num1, Pro* memory1);	

int main(void)
{
	int i;
	int curmemory;		//调入内存中的页面个数
	int missNum;		//缺页次数
	float missRate;		//缺页率
	char c;				//得到用户的输入字符,来选择相应的置换算法

	Pro* page;			//作业页面集
	Pro* memory;		//内存页面集

	printf("请输入所需要访问的页面总数:");
	scanf_s("%d", &pageNum);
	printf("请输入物理块的数量:");
	scanf_s("%d", &memoryNum);

	page = (Pro*)malloc(sizeof(Pro) * pageNum);
	memory = (Pro*)malloc(sizeof(Pro) * memoryNum);

	printf("访问的页面号将随机生成,生成的页面号为:");
	srand((unsigned int)time(NULL));
	for (i = 0; i < pageNum; i++)
	{
		//scanf_s("%d", &page[i].num);
		page[i].num= rand() % (pageNum-1);
		printf("%d ",page[i].num);
		page[i].time = 0;			//等待时间开始默认为0
	}
	printf("\n");

	do {
		for (i = 0; i < memoryNum; i++)		//初始化内存中页面
		{
			memory[i].num = -1;				//页面为空用-1表示
			memory[i].time = -1;			
		}

		printf("----- 1.FIFO   2.OPT   3.LRU   4.LFU ----- \n");
		printf("*****请选择操作类型,按其它键结束******\n");
		//fflush(stdin);
		getchar();
		scanf_s("%c", &c);

		i = 0;
		curmemory = 0;

		if (c == '1')			//FIFO页面置换
		{
			missNum = 0;

			printf("页面置换情况:   \n");
			for (i = 0; i < pageNum; i++)
			{
				if (Search(page[i].num, memory) < 0)//若在内存中没有找到该页面
				{
					missNum++;
					memory[curmemory].num = page[i].num;
					print(memory);
					curmemory = (curmemory + 1) % memoryNum;   //找出最先进入内存的页面
				}else
					print(memory);
			}//end for
			missRate = (float)missNum / pageNum;
			printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

		}//end if

		if (c == '2')			//OPT页面置换算法
		{
			missNum = 0;
			curmemory = 0;

			printf("页面置换情况:   \n");
			for (i = 0; i < pageNum; i++)
			{
				if (Search(page[i].num, memory) < 0)//若在内存中没有找到该页面
				{

					//找出未来最长时间内不再被访问的页面
					int tem;
					int opt = 0;
					for (int k = 0; k < memoryNum; k++)
					{
						if (memory[k].num == -1)
						{
							curmemory = k;
							break;
						}
						tem = 0;       //页面k在未来tem时间内不会出现
						int j;
						for (j = i + 1; j < pageNum; j++)
						{
							if (page[j].num == memory[k].num)
							{
								if (tem > opt)
								{
									opt = tem;
									curmemory = k;
								}
								break;
							}
							else tem++;
						}
						if (j == pageNum)
						{
							opt = tem;
							curmemory = k;
						}
					}

					missNum++;
					memory[curmemory].num = page[i].num;
					print(memory);
				}
				else
					print(memory);
			}//end for
			missRate = (float)missNum / pageNum;
			printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

		}//end if

		if (c == '3')			//LRU页面置换算法
		{
			missNum = 0;
			curmemory = 0;

			printf("页面置换情况:   \n");
			for (i = 0; i < pageNum; i++)
			{
				int rec = Search(page[i].num, memory);
				if (rec < 0)    //若在内存中没有找到该页面
				{
					missNum++;
					for (int j = 0; j < memoryNum; j++)     //找出最近最久未使用的页面
						if (memory[j].time == -1) {
							curmemory = j; break;
						}
						else if (memory[j].time > memory[curmemory].time)
							curmemory = j;

					memory[curmemory].num = page[i].num;
					memory[curmemory].time = 0;
					print(memory);

				}
				else
				{
					memory[rec].time = 0;
					print(memory);
				}

				for (int j = 0; j < memoryNum; j++)     //内存中的所有页面等待时间+1	
					if (memory[j].num != -1)
						memory[j].time++;

			}//end for
			missRate = (float)missNum / pageNum;
			printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);
		}//end if

		if(c == '4')			//LFU页面置换算法
		{
			missNum = 0;
			curmemory = 0;
			int *counter;	// 每个页面分配一个计数器
			counter = (int*)calloc(pageNum, sizeof(int));
			for (i = 0; i < pageNum;i++)
				counter[i] = 0;		// 每个页面初始访问0次

			printf("页面置换情况:   \n");
			for (i = 0; i < pageNum; i++)
			{
				int rec = Search(page[i].num, memory);
				if (rec < 0)    //若在内存中没有找到该页面
				{
					missNum++;
					// 寻找在物理块中的页面里访问次数最少的
					int min = 0;
					for (int j = 0; j < memoryNum; j++)
					{
						if (memory[j].num == -1)
						{
							min = j;
							break;
						}
						else if(counter[memory[j].num] < counter[memory[min].num])
							min = j;
					}
					memory[min].num = page[i].num;
					counter[page[i].num]++;		// 最近使用次数+1
					print(memory);

				}	// 若在内存中找到了页面
				else
				{
					counter[page[i].num]++;		// 最近使用次数+1
				}

			}//end for
			missRate = (float)missNum / pageNum;
			printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);
		}//end if

	} while (c == '1' || c == '2' || c == '3'|| c == '4');


	return 0;
}


void print(Pro* memory1)//打印当前的页面
{
	int j;

	for (j = 0; j < memoryNum; j++)
		printf("%d ", memory1[j].num);
	printf("\n");
}

//在页面集memory1中查找num1,如果找到,返回其在memory1中的下标,否则返回-1
int  Search(int num1, Pro* memory1)
{
	int j;

	for (j = 0; j < memoryNum; j++)
	{
		if (num1 == memory1[j].num)
			return j;
	}
	return -1;
}

NJUPT南邮 | 操作系统_实验一 页面置换算法_第1张图片
NJUPT南邮 | 操作系统_实验一 页面置换算法_第2张图片

你可能感兴趣的:(南邮实验,操作系统,c++)