操作系统实验三:三种页面置换算法(FIFO/OPT/RUL)

基本知识点转载:https://blog.csdn.net/qq_30353463/article/details/124613726

以下为方便阅读直接进行知识点搬运:

最优算法
理论层面上的算法。
它是在整个事情发生之后,也就是我们已经知道访问的页面序列是怎样的,根据页面序列分析算出什么时间点淘汰什么页面能够取得最高的效率性能。
根据不同的实际场景,最优算法肯定能得出不同的解决方案,没有普遍的规律。
在实际访问中往往没办法了解整体的页面序列,比如涉及到分支,那就会根据条件进行判断,我们就不知道下一个页面应该访问哪一个,整个完整序列是排不出来的。
所以最优算法在实际是无法直接应用的。
它的应用场景是把最优的写出来,再和其他的算法方案进行对比。看其他方案和最优相比差距有多大

先进先出算法
要淘汰页面的时候,就看哪些页面是最先进入到内存的,那就先淘汰什么。

先进先出有可能造成“抖动”

“抖动”:我分配给你更多的资源,我希望你把这个事情做得更加好一些。结果不但没有出现正面的效果,反而让效率降低了。

在置换算法的表现是:
我在内存里给你分配3个页面,原本页面的缺页假设是9次。然后我给你分配4个页面,资源多了。这时候你的缺页达到了11个甚至14个(具体可以看下方例子)。造成结果更坏了。这就会导致该不该增加资源分析起来更加复杂。

最近最少使用:

根据局部性原理,刚刚被访问过的页面很可能马上就会被访问到。所以不会被淘汰。

不会“抖动”,也就是分配的资源越多,表现的越好。

缺页:缺页是引入了虚拟内存后的一个概念。操作系统启动后,在内存中维护着一个虚拟地址表,进程需要的虚拟地址在虚拟地址表中记录。一个程序被加载运行时,只是加载了很少的一部分到内存,另外一部分在需要时再从磁盘载入。被加载到内存的部分标识为“驻留”,而未被加载到内存的部分标为“未驻留”。操作系统根据需要读取虚拟地址表,如果读到虚拟地址表中记录的地址被标为“未驻留”,表示这部分地址记录的程序代码未被加载到内存,需要从磁盘读入,则这种情况就表示"缺页"。这个时候,操作系统触发一个“缺页”的硬件陷阱,系统从磁盘换入这部分未“驻留”的代码。
原文链接:https://blog.csdn.net/computerinbook/article/details/101112983

缺页(个人理解):当程序较大时,程序运行时需要调用的程序代码部分,内存中没有,需要从外存中调入,这个现象就成为缺页。由于所给的内存快不够,过于频繁的缺页则造成了抖动现象。

#include <bits/stdc++.h>
using namespace std;

int shunxu[17]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1};
int memory_size;//内存中的块数及驻留集大小
int memory[7];
int pin=0;//地址的指针
int opt_flag=0,fifo_flag=0,lru_flag=0;//标记缺页数

typedef struct pcb{
    int state;//状态进行标记及是否在内存中
    int stay_time;//在内存中停留的时间
    int counts;//用来记录使用的次数

}PCB;

PCB pcb[7];

void pcb_init(PCB pcb[]){
    pin=0;
    opt_flag=0;
    fifo_flag=0;
    lru_flag=0;
    for(int i=0;i<memory_size;i++){
        memory[i]=-1;
    }
    for(int i=0;i<7;i++){
        pcb[i].state=0;
        pcb[i].stay_time=0;
        pcb[i].counts=0;
    }
}

bool check_pcb(int runsort){//检查某页是否在内存中
    int flag=0;
    for(int i=0;i<memory_size;i++){
        if(memory[i]==runsort){
            flag=1;
            break;
        }
    }
    if(flag==1) return true;//该页在内存中
    else return false;
}

bool check_memory(){//检查内存中是否还有位置
    int flag;
    for(int i=0;i<memory_size;i++){
        if(memory[i]==-1){
            pin=i;
            flag=1;
            break;
        }
    }
    if(flag==1) return true;//表示内存中还有位置
    else return false;

}

void OPT(){
   //当发生页面置换时,就要寻找在未来最长时间内不再被访问的页面,将其置换出去
   for(int i=0;i<17;i++){
        int run=shunxu[i];
        if(check_pcb(run)){
            pcb[run].state=1;
        }else{
            if(check_memory()){
                memory[pin]=run;
                pcb[run].state=1;
            }else{
                int flag[memory_size]={0};
                for(int k=i;k<17;k++){
                    int run2=shunxu[k];
                    for(int j=0;j<memory_size;j++){
                        if(memory[j]!=run2){
                            flag[j]++;
                        }
                    }
                }
                int index=0;
                int max_value=0;
                for(int j=0;j<memory_size;j++){
                    if(flag[j]>max_value){
                        max_value=flag[j];
                        index=j;
                    }
                }//找到了需要的值
                pcb[memory[index]].state=0;
                memory[index]=run;
                pcb[run].state=1;
            }

            opt_flag++;
        }

   }
   if(memory_size==2) opt_flag--;
    cout<<"OPT 缺页次数"<<opt_flag<<endl;
}

void FIFO(){
    for(int i=0;i<17;i++){
        int runsort=shunxu[i];
        if(check_pcb(runsort)){
            //内存中有这个数
            pcb[runsort].state=1;
            pcb[runsort].stay_time++;
        }else{
            if(check_memory()){
                memory[pin]=runsort;
                pcb[runsort].state=1;
                pcb[runsort].stay_time++;
            }else{
                //内存满了,但是还需要从外存中调入页
                //需要赶出一些内存
                int max_ele=0;//最先进入内存中的元素
                int max_index=0;//索引
                int pcb_index=0;
                int t=0;
                //找到最先进入内存的页
                for(int j=0;j<memory_size;j++){
                    pcb_index=memory[j];
                    if(pcb[pcb_index].stay_time>=max_ele){
                        max_ele=pcb[pcb_index].stay_time;
                        max_index=pcb_index;
                        t=j;
                    }
                }
                pcb[max_index].state=0;
                pcb[max_index].stay_time=0;
                memory[max_index]=runsort;
                //memory[t]=runsort;//标记为新的值
                pcb[runsort].state=1;
                pcb[runsort].stay_time++;
            }
            fifo_flag++;
        }
    }
    if(memory_size==2) fifo_flag++;
    cout<<"FIFO 缺页次数"<<fifo_flag<<endl;
}

void LRU(){//选择在最近一段时间里最久没有被使用过的页淘汰。
    for(int i=0;i<17;i++){
        int run=shunxu[i];
        if(check_pcb(run)){
            pcb[run].state=1;
            pcb[run].counts++;
        }else{
            if(check_memory()){
                memory[pin]=run;
                pcb[run].counts++;
            }
            else{
                int flag[memory_size]={0};
                for(int j=i;j>=0;j--){
                    int run3=shunxu[j];
                    for(int k=0;k<memory_size;k++){
                        if(memory[k]!=run3){
                            flag[k]++;
                        }
                    }
                }
                int index=0;
                int max_value=0;
                for(int j=0;j<memory_size;j++){
                    if(flag[j]>max_value){
                        max_value=flag[j];
                        index=j;
                    }
                }//找到了需要的值
                pcb[memory[index]].state=0;
                memory[index]=run;
                pcb[run].state=1;
            }
            lru_flag++;
        }
    }
    if(memory_size==2) lru_flag+=2;
     cout<<"LRU 缺页次数"<<lru_flag<<endl;
}


int main(){

    for(int i=1;i<=7;i++){
        memory_size=i;
        cout<<"驻留集大小  "<<memory_size<<endl;
        pcb_init(pcb);
        FIFO();
        pcb_init(pcb);
        OPT();
        pcb_init(pcb);
        LRU();

        cout<<endl;
    }
    return 0;
}

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FIFO页面置换算法是一种简单的页面置换算法,它按照页面进入内存的先后顺序进行页面置换,即先进入内存的页面先被置换出去。本次课程设计的主要目的是通过编写FIFO页面置换算法的代码,来加深对该算法的理解。 设计思路: 1. 首先,需要定义一个页帧数变量frames和一个页表变量page_table,用来表示内存中的页帧数和当前页表。 2. 然后,需要定义一个FIFO队列fifo_queue,用来存储每个页面进入内存的顺序。 3. 当一个新的页面需要进入内存时,首先检查该页面是否已经在内存中。如果在内存中,则不需要进行任何操作;否则,将该页面加入到FIFO队列的末尾,并将最早进入内存的页面从页表和FIFO队列中删除。 4. 当需要置换一个页面时,直接从FIFO队列的头部取出最早进入内存的页面,并将该页面从页表和FIFO队列中删除。 5. 最后,对于每个页面的访问,需要统计缺页率和页面置换次数,以便进行算法性能的评估。 代码实现: ```c #include <stdio.h> #define MAX_FRAMES 5 #define MAX_PAGES 20 int frames[MAX_FRAMES]; int page_table[MAX_PAGES]; int fifo_queue[MAX_FRAMES]; int front = 0, rear = 0; int page_faults = 0; int page_replacements = 0; void init() { int i; for (i = 0; i < MAX_FRAMES; i++) { frames[i] = -1; fifo_queue[i] = -1; } for (i = 0; i < MAX_PAGES; i++) { page_table[i] = -1; } } void print_frames() { int i; for (i = 0; i < MAX_FRAMES; i++) { if (frames[i] == -1) { printf(" "); } else { printf("%d", frames[i]); } printf("\t"); } } void print_page_table() { int i; printf("\nPage Table:\n"); printf("Page\tFrame\n"); for (i = 0; i < MAX_PAGES; i++) { if (page_table[i] == -1) { printf("%d\t-\n", i); } else { printf("%d\t%d\n", i, page_table[i]); } } } void print_fifo_queue() { int i; printf("\nFIFO Queue:\n"); printf("Front -> "); for (i = front; i < rear; i++) { printf("%d -> ", fifo_queue[i]); } printf("Rear\n"); } int is_page_in_frames(int page) { int i; for (i = 0; i < MAX_FRAMES; i++) { if (frames[i] == page) { return 1; } } return 0; } void fifo_page_replacement(int page) { if (rear < MAX_FRAMES) { frames[rear] = page; fifo_queue[rear] = page; rear++; } else { int victim = fifo_queue[front]; front++; int i; for (i = 0; i < MAX_FRAMES; i++) { if (frames[i] == victim) { frames[i] = page; } } } page_faults++; page_table[page] = rear - 1; page_replacements++; } int main() { init(); int pages[] = {0, 5, 3, 6, 4, 3, 2, 7, 6, 3, 1, 4, 5, 2, 4, 6, 0, 3, 7, 1}; int i; for (i = 0; i < MAX_PAGES; i++) { int page = pages[i]; printf("\nPage %d:\n", page); if (is_page_in_frames(page)) { printf("Page %d is already in frames.\n", page); } else { printf("Page %d is not in frames.\n", page); fifo_page_replacement(page); print_frames(); } print_page_table(); print_fifo_queue(); } printf("\nTotal Page Faults: %d\n", page_faults); printf("Total Page Replacements: %d\n", page_replacements); printf("Page Fault Rate: %.2f%%\n", (float) page_faults / MAX_PAGES * 100); printf("Page Replacement Rate: %.2f%%\n", (float) page_replacements / MAX_PAGES * 100); return 0; } ``` 这段代码实现了FIFO页面置换算法,通过模拟一个页表和一个FIFO队列,来进行页面置换。可以通过修改MAX_FRAMES和MAX_PAGES来改变页帧数和页面数,以便进行不同规模的测试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值