C语言版操作系统实验:FIFO与LRU页面置换算法

实验要求:

计算并输出下述各种算法在内存容量为3块、4块下的缺页率。

1.先进先出的算法(FIFO);

要求用数组或链表方法实现

2.最近最少使用算法(LRU)。

   要求用计数器或堆栈方法实现

 

代码及注释如下:

(FIFO用的是数组,LRU用堆栈)

#include<stdio.h>
#include<stdlib.h>
#define PN 20//页面访问列长度
#define FN 3//分配给进程的内存块数
#define FN1 4//分配给进程的内存块数 

int *pageSeq;//页面访问序列
int *frames;//内存块数组
int fault,exchange;//缺页次数和置换次数
float ratio;//缺页率

void init();//初始化页面访问向量
void clear();//初始化内存块
void print();//输出最后结果
void print1(int);//输出每一步结果
void FIFO(int*,int,int*,int);//FIFO算法
void LRU(int*,int,int*,int);//LRU算法
int search(int,int*,int,int);//搜索页面在序列某段中的位置,找到返回下标,否则返回-1

int main()
{
int num;
printf("【页面置换算法】\n");
printf("序列长度:%d\n",PN);
printf("内存块数:%d或%d\n",FN,FN1);
printf("========================\n\n\n");
    init();//初始化页面访问向量
    printf("操作说明:\n");
    printf("    num=0  程序结束\n");
    printf("    num=1  FIFO算法(页面数为3)\n");
    printf("    num=2  LRU算法(页面数为3)\n");
    printf("    num=3  FIFO算法(页面数为4)\n");
    printf("    num=4  LRU算法(页面数为4)\n");
    printf("==============================\n");
    printf("\n");
    printf("输入操作序号num:");
    scanf("%d",&num);
    while(1)
    {
        switch(num)
        {
            case 0:printf("\n=====程序结束!=====\n");return 0;
            case 1:printf("\n【FIFO算法】页面为3页\n");FIFO(pageSeq,PN,frames,FN);break;
            case 2:printf("\n【LRU算法】页面为3页\n");LRU(pageSeq,PN,frames,FN);break;
            case 3:printf("\n【FIFO算法】页面为4页\n");FIFO(pageSeq,PN,frames,FN1);break;
            case 4:printf("\n【LRU算法】页面为4页\n");LRU(pageSeq,PN,frames,FN1);break;
            default:printf("\n=====无效选项!请重新输入=====\n");goto L1;
        }
        print();
L1:     printf("\n");
        printf("输入操作序号num:");
        scanf("%d",&num);
    }
}

void init()//输入访问序列
{
    int i;
    pageSeq=(int*)(malloc(PN*sizeof(int)));//动态分配内存 

    frames=(int*)(malloc(FN*sizeof(int)));//动态分配内存 
  
    printf("向pageSeq输入页面访问序列:");
    for(i=0;i<PN;i++)
        scanf("%d",&pageSeq[i]);
    printf("\n");
    printf("页面访问序列:\n\n");//输出页面访问序列
    for(i=0;i<PN;i++)
        printf("%3d",pageSeq[i]);
    printf("\n\n");
    printf("===============================================================\n");
}

void clear()//重新初始化内存块frames,因为有0号页面,所以置-1
{
    int i;
    fault=0;//缺页次数
    exchange=0;//置换次数
    for(i=0;i<FN;i++)//内存块置-1
        frames[i]=-1;
}

void print1(int flag)//flag为缺页标志,输出每一步结果
{
    int t;
    for(t=0;t<FN;t++)//每访问一个页面,都输出一次内存块(页面)
        printf("% d",frames[t]);
    if(flag) printf("  fault");//在缺页位置标记“fault”
    printf("\n");
}

void print()//输出最后结果
{
    exchange=fault-FN;
    ratio=(float)fault/PN*100;
    printf("------------------------------\n");
    printf("缺页次数:%d\n",fault);
    printf("置换次数:%d\n",exchange);
    printf("缺 页 率:%4.1f%%\n",ratio);
    printf("==============================\n");
}

int search(int p,int* ar,int start,int end)//参数说明:(页号,页面访问序列或者内存块数组,起点,终点)
{//检测页面p是否存在数组ar中(起点start,终点end),存在则返回其在ar中的位置(下标),否则返回-1
    int i,f;
    if(start>end)f=-1;//f作为方向标志,f=1时,循环变量递增;f=-1时,循环变量递减
    else f=1;
    i=start;//从strat位置开始搜索
    while(i!=end+f)//i超过end时结束循环
    {
        if(p==ar[i])return i;//首次搜索到p即返回下标    
        i=i+f;
    }
    return -1;//未搜索到页面p,即p在未来不再被访问
}


void FIFO(int* arp,int p,int* arf,int f)
{//参数说明:(页面访问序列数组,数组长度,内存块数组,数组长度)
    int i,j=0,flag;
    clear();//内存块数据清零
    printf("页面访问过程:\n");
    printf("------------------------------\n");
    for(i=0;i<p;i++)
    {
        flag=0;//缺页标志
        if(search(arp[i],arf,0,f-1)==-1)//如果当前页面arp[i]不在内存
        {
            fault++;//缺页+1
            flag=1;
            arf[j]=arp[i];//页面调入内存
            j=(j+1)%f;//j+1,循环
        }
        print1(flag);//输出一次内存页面情况
    }
}

void LRU(int* arp, int p, int* arf, int f) {
    int i, j;
    int kf = 0;  // kf>=f时,内存块满,此时缺页产生置换
    int* pageStack = (int*)malloc(p * sizeof(int));  // 用于保存页面访问顺序的堆栈
    int* pageMap = (int*)malloc(f* sizeof(int));  // 用于保存页面在堆栈中的位置

    clear();

    for (i = 0; i < p; i++) {
        int flag = 0;
        if (search(arp[i], arf, 0, f - 1) == -1) {  // 页面不在内存
            flag = 1;
            fault++;  // 缺页
            if (kf < f) {  // 有空闲块,无置换
                arf[kf] = arp[i];
                pageStack[kf] = arp[i];
                pageMap[arp[i]] = kf;
                kf++;
            } 
			else {  // 无空闲块,产生置换
                int pmini = p;  // pmini值初值(最大值或者当前值i)
                int pminj = -1;
                for (j = 0; j < f; j++) {
                    int posi = search(arf[j], arp, i - 1, 0);  // 不会出现页面不存在的情况
                    if (posi < pmini) {
                        pmini = posi;
                        pminj = j;
                    }
                }
                if (pminj != -1) {
                    for (j = pminj; j < f - 1; j++) {
                        arf[j] = arf[j + 1];  // 置换
                    }
                    arf[f - 1] = arp[i];
                    pageStack[f - 1] = arp[i];
                    pageMap[arp[i]] = f - 1;
                }
            }
        }
        print1(flag);  // 输出一次内存页面情况
    }

    free(pageStack);
    free(pageMap);
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值