【OS】FIFO先入れ先出しページ置換アルゴリズム(C言語実装)

FIFO ページ置換アルゴリズム、ページ フォールト率の計算、記事の最後のコード、およびサンプル分析

1. 内容

アドレス マッピングプロセス        中に、アクセスするページがメモリ内にないことが判明した場合、ページ フォルト割り込みが生成されます。ページ フォールトが発生し、オペレーティング システムのメモリに空きページがない場合、オペレーティング システムはメモリ内のページを選択し、それをメモリから移動して、ページを転送するためのスペースを確保する必要があります。削除するページを選択するために使用される規則は、ページ置換アルゴリズムと呼ばれます。

        メモリのページング管理をシミュレートし、メモリの割り当てと呼び出しを実現し、仮想メモリ アドレス シーケンスと物理メモリの間の対応を完成させます。メモリ呼び出しでページ フォールトが発生すると、プログラムのメモリ ページが転送されます。空きページがない場合、ページの置換は先入れ先出し (FIFO) アルゴリズムを使用して実装されます。

2. ページの構造

ページの構成は次のとおりです。

  ページ番号、ページ番号、タイムスタンプ (このアルゴリズムでは使用されず、LRU で使用されます)

名前

シンボル

関数

ページ番号

ページ番号

ページ番号を記録する

ページ番号

Pframe_num

ページ番号を記録する

      FIFO ページ置換アルゴリズムは、最も長く (つまり、最も古い) 置換のためにメイン メモリにとどまるページ、つまり、最初にメモリに入り、最初にメモリから出るページを選択します。その理由は、最初にメモリに転送されたページは、メモリに転送されたばかりのページよりも使用されなくなる可能性が高いためです。すべてのページをメモリに保持するための FIFO キューを作成します。置き換えられたページは、常にキューの先頭で実行されます。ページがメモリに取り込まれると、キューの最後に挿入されます

       線形テーブルを使用してページ テーブルを実装することにより、ページを削除する必要があるたびに、最初に入力されたページが削除されるため、メイン メモリに最も長く滞在するページが削除されます。

プロセスは次のとおりです。

3. 分析例

ページ管理システムでは、アクセスの順番(アクセス文字列)は 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 で、割り当てページ数が 3 の場合は、次の(1)置換アルゴリズムをそれぞれ用いてページフォルト数を計算し、ページ置換図を描きなさい。

(1) FIFO。

アクセス文字列 1 2 3 4 1 2 5 1 2 3 4 5
ページ1 1 2 3 4 1 2 5 5 5 3 4 4
2ページ 1 2 3 4 1 2 2 2 5 3 3
3ページ 1 2 3 4 1 1 1 2 5 5
ページフォルトはありますか はい はい はい はい はい はい はい いいえ いいえ はい はい いいえ

ページ フォールト率: 9/12=0.75

4. コードは次のとおりです。

#define _CRT_SECURE_NO_WARNINGS 1


#include <stdio.h>
#include <stdlib.h>

#define MAX_PAGES 20
#define MAX_PFRAME 20
#define INVALID -1

typedef struct {
	int page_num;
	int pframe_num;
	int count;
	int timestamp;
}page_type;

page_type page[MAX_PAGES];

typedef struct pf_struct {
	int pframe_num;//页面号
	struct pf_struct* next;
}pf_type;

pf_type pframe[MAX_PFRAME];

int diseffct = 0;//缺页记录

void InitPage(const int* page_n, const int* pframe_n)
{
	int total_vp = *page_n, total_pf = *pframe_n;
	int i = 0;
	diseffct = 0;
	for (i = 0; i < total_vp; i++)//虚拟页
	{
		page[i].page_num = i;
		page[i].pframe_num = INVALID;
		page[i].count = 0;
		page[i].timestamp = -1;
	}
	for (i = 0; i < total_pf - 1; i++)
	{
		pframe[i].next = &pframe[i];
		pframe[i].pframe_num = i;
	}
	pframe[total_pf - 1].next = NULL;
	pframe[total_pf - 1].pframe_num = total_pf - 1;
}


double miss_page_rate(int pframe_order[100]) {
	int i = 0;
	double missrate = 0, count = 0;
	while (pframe_order[i] != -1)
	{
		count++;
		i++;
	}
	missrate = diseffct / count;
	return missrate;
}

void menu(int* page_n, int* pframe_n)
{
	int a, b;
	printf("---------------------------------------------\n");
	printf("请输入页面的数量:");
	scanf("%d", page_n);
	printf("请输入页的数量:");
	scanf("%d", pframe_n);
	printf("--------------------------------------------\n");
}

int get_input_order(int fprame_order[100], int pframe_n)
{
	int p = 0;
	int tmp = 0;
	printf("请输入访问串(1到%d中的数字,每输入一个数输入一次回车,输入-1表示结束):\n", pframe_n);
	while (1)
	{
		scanf("%d", &tmp);
		fprame_order[p] = tmp;
		p++;
		if (tmp == -1)
		{
			break;
		}
	}

	return p;
}

int check_all_page(int page_num, int target)
{
	int judge = 0;
	for (int i = 0; i < page_num; i++)
	{
		if (page[i].pframe_num == target)
		{
			judge = 1;
		}
	}
	if (judge == 1)
	{
		return 1;
	}
	else
	{
		diseffct++;//全程序只在本处处理缺页次数
		return 0;
	}
}

void display(int page_num, int judge)//就是打印出所有的页
{
	printf("页面号\t页号\t时间戳\n");
	for (int i = 0; i < page_num; i++)
	{
		printf("%d\t%d\t%d\n", page[i].page_num, page[i].pframe_num, page[i].timestamp);
	}
	if (judge == 1) {
		printf("不缺页\n");
	}
	else
	{
		printf("缺页\n");
	}
}

void FIFO(int page_num, int pframe_id)//page_num为页的数量,pframe_id为页面号
{
	int i, j;
	pf_type* p;
	for (i = page_num - 2; i >= 0; i--)
	{
		//page[i + 1].count = page[i].count;
		page[i + 1].pframe_num = page[i].pframe_num;
	}
	page[0].pframe_num = pframe_id;
}

void execute_pagef(int pframe_order[100], int page_num)//page_num为虚拟页的数量,page_n指针和page_num的值一样
{
	int i = 0, jugde = 0;
	while (pframe_order[i] != -1)
	{
		printf("************************************\n");
		printf("使用页 %d\n", pframe_order[i]);
		jugde = check_all_page(page_num, pframe_order[i]);
		if (jugde == 1) {//在虚拟页内
			i++;
		}
		else//不在页内就调用页面置换算法
		{
			FIFO(page_num, pframe_order[i]);
			i++;
		}
		display(page_num, jugde);
	}
}



int main()
{
	int* page_n = (int*)malloc(sizeof(int));
	int* pframe_n = (int*)malloc(sizeof(int));
	int pframe_order[100];
	int order_num = 0;
	menu(page_n, pframe_n);
	InitPage(page_n, pframe_n);
	order_num = get_input_order(pframe_order, *pframe_n);
	execute_pagef(pframe_order, *page_n);
	//printf("%d %d\n", *page_n, *pframe_n);
	printf("\n缺页率为: %lf", miss_page_rate(pframe_order));
	free(page_n);
	free(pframe_n);
	return 0;
}

5. 次のように実行します。

プログラムは 5 ページに分割され、メモリには 3 ページあり、アクセス順序は 1、2、3、2、4、5、2 です。

ページ フォールト率: 0.857143

おすすめ

転載: blog.csdn.net/peng_lv/article/details/128191598