无敌是多么多么寂寞【操作系统FIFO及LRU算法C语言实现】

诶亚麻好久没有更博了TnT太忙了最近真的,从开学到现在一个周末都没有,没有什么比改好bug更让人兴奋的事情了哈哈哈哈。趁着刚实现完算法的这一会,总结一下OS页面置换两个算法:先进先出最久未使用

先解释两个概念
缺页 : 就是内存中没有,需要从外存调入页面。
缺页率: 缺页次数/总页面访问数

我的教材是西安电子科技大学的操作糸统第四版,直接采用书上的数据。

#define M 3
#define PAGES 20
int page[PAGES] = {7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
int result[M][PAGES];//保存结果的矩阵
typedef struct {
    int page;//内存块中的页面号
    int time;//此页面在内存中停留的时间
}pBlock;//定义内存块的结构体

FIFO算法

算法思想

谁先进来谁先走。定义一个替换指针sw,sw永远指向的是内存中最早进来的那一块的块号sw = (sw+1)%M

/*初始化内存矩阵*/
void init(pBlock *pb){
    int i,j;
    for(i = 0;i1;
        pb[i].time = -1;
        for(j = 0; j 1;
        } 
    }
}

/*查询内存块中是否有当前页面*/
int isHavePage(pBlock *pb,int page){
    int i,j;
    int flag = 0;
    for(i = 0; i < M;i++){
        if(pb[i].page == page){
            flag = 1;
            break;
        }
    }
    return flag;
}

void printPage(int *page,int m){
    int i = 0;
    for(i = 0; i < m ;i++){
        printf("%d ",page[i]);
    }
    printf("\n");
}

void printResultArr(int result[M][PAGES]){
    int i, j;
    for (i = 0; ifor (j = 0; jif (result[i][j] == -1)
                printf("_ ");
            else
                printf("%d ", result[i][j]);
        }
        printf("\n");
    }
}

void fifo(pBlock *pb){
    int lps = 0; //缺页次数
    double lpp = 0;//缺页率 
    int sw = 0;//替换指针
    int index;//页面号索引 
    int i;
    while(index < PAGES){
        if(!isHavePage(pb,page[index])){//如果该页面不在内存块中,pb:内存块,page[index]当前页面 
            pb[sw].page = page[index];
            sw = (sw + 1) % M;
            lps++;
            for( i =0; i < M ;i++){
                result[i][index] = pb[i].page;
            }
        }
        index++;
    }
    printf("FIFO算法所得缺页次数为 %d\n", lps);
    lpp = (double)lps / PAGES;
    printf("FIFO算法缺页率为 %0.4lf \n", lpp);
    printf("页面号序列为:\n");
    printPage(page, PAGES);
    printf("结果数列为:\n");
    printResultArr(result);

}

LRU最近最久未使用算法

算法核心:内存中的块都有有个时间标识t,初始给所有的内存块t赋值为-1,新加进来之后设置t值为0,当既不是被替换的块、也不是新加进来的块,t值++,每次替换t最大的内存块。

/*返回要被替换的页面所在的内存快号*/
int getLong(pBlock *pb){
    int i;
    int sw = 0;
    int in = 1;//可以替换的物理块的值设为1 
    for(i = 0; i < M;i++){
        if(pb[i].time == -1){//如果内存块中为空,则往里面可以添加页面 ,跳出循环
            sw = i;//替换指针所指的物理块赋值为空的物理块索引号
            in = 0;//已经放进来东西了之后,可继续添加的页面块数-1 赋值为0 
            break;
        }
    }
    /*当还没有添加页面时,说明内存块已满,需要替换*/
    if(in){
        for(i = 0;i < M;i++){
        //  printf("pb[%d].time = %d\n",i,pb[i].time); 
            if(pb[i].time > pb[sw].time){//如果内存块第i块中页面的时间量大于可以可替换页面的的时间量,则替换最久没用的页面 
                sw = i;
            }
        }
    }
    return sw;
}
/*找到该页面在第几个内存块*/
int findPage(pBlock *pb,int page){
    int i;
    int num = -1;
    for (i = 0; iif (pb[i].page == page) {
            num = i;
        }
    }
    return num;
}

void LRU(pBlock *pb){
    int lps = 0; //缺页次数
    double lpp = 0;//缺页率 
    int sw = 0;//替换指针,取值范围为0-2 
    int index = 0;
    int i;
    while(indexif(!isHavePage(pb,page[index])){//如果没有当前页,获取内存块中时间最久的页面所在的内存块号,并替换。 
            sw = getLong(pb);
        //  printf("index:%d ,sw:%d \n",index,sw); 
            pb[sw].page = page[index];
            pb[sw].time = 0;
            lps++;
            for(i = 0; i < M ;i++){
                if(i != sw && pb[i].time != -1 ){//如果i不是替换页面并且不是初始化之前的时间 
                pb[i].time++;

                }
            result[i][index] = pb[i].page;
            }
        }else{
            int num_inblock = findPage(pb,page[index]); 
        //  printf("找到的内存号为:%d\n",num_inblock); 
            pb[num_inblock].time = 0;
        //  printf("index:%d,已含有\n",index);
            for(i = 0;i < M ;i++){
                if(i!= num_inblock){
                    pb[i].time++;
                }
            }
        }
        index++;
    }
    printf("LRU算法所得缺页次数为 %d \n", lps);
    lpp = 1.0*lps / PAGES;
    printf("LRU算法缺页率为: %0.4lf\n", lpp);
    printf("页面号序列为:\n");
    printPage(page, PAGES);
    printf("LRU结果数组为:\n");
    printResultArr(result);
}

以上就是今天在打了一盘LOL之后的结果。回宿舍睡觉觉啦
QQ:396558528
github
如果有错误欢迎指正,一起学习,一起进步。

你可能感兴趣的:(操作系统)