#include <stdio.h>
#include <stdlib.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define INVALID -1 //-1表示缺頁
////頁表結構類型
typedef struct pl_type {
int pn; //頁號
int fn; //頁面號
int time; //訪問時間
int dist; //下次訪問離當前頁的距離
}pl_type;
//頁面鏈結構類型
typedef struct fl_type {
int pn; //頁號
int fn; //頁面號
struct fl_type *next; //鏈接指針
}fl_type;
//結構變量
pl_type pl[512]; //頁表
fl_type fl[512],*free_head,*busy_head,*busy_tail; //頁面
int page[512]; //訪問串(訪問的頁號序列)
int total_pages; //訪問串長度
int diseffect; //缺頁數
//初始化函數
//形參frame_number爲分配給用戶進程的內存頁面數
void initialize(int frame_number)
{
int i;
diseffect=0; //頁故障數初始化爲0
//建立空頁表
for(i=0;i<512;i++) {
pl[i].pn=i; //頁號
pl[i].fn=INVALID; //頁面號爲空,(開始時,頁還未裝入到頁面)
pl[i].time=0; //時間爲0
}
//建立空閒頁面鏈
for(i=1;i<frame_number;i++) {
fl[i-1].next=&fl[i]; //建立fl[i-1]和fl[i]間的鏈接
fl[i-1].fn=100+i-1;//頁面號由系統分配,可以是其他值,例如從100開始,fl[i-1].fn=100+i-1;
}
fl[frame_number-1].next=NULL; //鏈表末尾爲空指針
fl[frame_number-1].fn=100+frame_number-1; //末尾結點的頁面號
free_head=&fl[0]; //空頁面隊列的頭指針指向fl[0]
}
//OPT函數:計算OPT算法下的缺頁率
void OPT(int frame_number)
{
int i;
initialize(frame_number); //初始化頁表和頁面鏈
busy_head=free_head;
for(i=0; i<total_pages; i++) {
if(pl[page[i]].fn==INVALID) { //查頁表,若缺頁
diseffect++; //記錄缺頁數
if(free_head==NULL){ //若無空閒頁面, 下面3句置換忙頁面鏈頭結點
pl[busy_head->pn].fn=INVALID; //淘汰忙頁面鏈頭結點
busy_head->pn=page[total_pages%(i+total_pages/2)]; //忙頁面鏈頭結點裝入新頁
pl[page[total_pages%(i+total_pages/2)]].fn=busy_head->fn; //修改頁表
busy_tail->next=busy_head; //這4句把忙頁面鏈頭結點移動到尾部
busy_head=busy_head->next;
busy_tail=busy_tail->next;
busy_tail->next=NULL;
}else{ //若有空閒頁面, 下面3句直接裝入新頁
free_head->pn=page[i]; //空閒頁面鏈頭結點裝入新頁
pl[page[i]].fn=free_head->fn; //修改頁表
free_head=free_head->next; //空閒頁面鏈頭指針前移
if(free_head) busy_tail=free_head; //記錄忙頁面鏈尾結點
}
}
}
//打印結果
printf("OPT: %02d次(缺頁數(缺頁率)爲%.02f%% 命中率爲%.02f%%)",diseffect,100.0*diseffect/total_pages,100-100.0*diseffect/total_pages);
}
//FIFO函數:計算FIFO算法下的缺頁率
void FIFO(int frame_number)
{
int i;
initialize(frame_number); //初始化頁表和頁面鏈
busy_head=free_head;
for(i=0; i<total_pages; i++) {
if(pl[page[i]].fn==INVALID) { //查頁表,若缺頁
diseffect++; //記錄缺頁數
if(free_head==NULL){ //若無空閒頁面, 下面3句置換忙頁面鏈頭結點
pl[busy_head->pn].fn=INVALID; //淘汰忙頁面鏈頭結點
busy_head->pn=page[i]; //忙頁面鏈頭結點裝入新頁
pl[page[i]].fn=busy_head->fn; //修改頁表
busy_tail->next=busy_head; //這4句把忙頁面鏈頭結點移動到尾部
busy_head=busy_head->next;
busy_tail=busy_tail->next;
busy_tail->next=NULL;
}else{ //若有空閒頁面, 下面3句直接裝入新頁
free_head->pn=page[i]; //空閒頁面鏈頭結點裝入新頁
pl[page[i]].fn=free_head->fn; //修改頁表
free_head=free_head->next; //空閒頁面鏈頭指針前移
if(free_head) busy_tail=free_head; //記錄忙頁面鏈尾結點
}
}
}
//打印結果
printf("FIFO: %02d次(缺頁數(缺頁率)爲%.02f%% 命中率爲%.02f%%)",diseffect,100.0*diseffect/total_pages,100-100.0*diseffect/total_pages);
}
//輸入訪問串
void Input_reference_string(void)
{
int i;
printf("輸入的訪問串,頁號間以空格分開。例如: 7 0 2 6\n");
printf("請輸入訪問串: ");
for(i=0;i<512;i++) {
if(scanf("%d", &page[i])!=1) break;
if(getchar()==0x0a && i>0) break;
}
total_pages=i+1; //訪問串大小
printf("訪問串大小:%d\n訪問串爲: ", total_pages);
for(i=0;i<total_pages;i++) printf("%d ", page[i]);
printf("\n\n");
}
int main()
{
int frames;
system("color f0");
Input_reference_string();
for(frames=2;frames<=total_pages;frames++){ //從2個頁面到total_pages個頁面
printf(" 分配%2d個頁面時,", frames);
OPT(frames);
//FIFO(frames);
printf("\n");
}
return 0;
}
#Linux# #代碼#頁面置換算法(FIFO和OPT)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.