操作系统A

李美蓉

目录

  • 1 操作系统引论
    • 1.1 计算机操作方式的演变
    • 1.2 什么是操作系统
    • 1.3 操作系统的结构
    • 1.4 操作系统的特性
  • 2 进程管理
    • 2.1 进程描述
    • 2.2 进程状态及转换
    • 2.3 进程控制
    • 2.4 进程的并发执行
    • 2.5 进程同步与互斥
    • 2.6 信号量机制及应用
    • 2.7 生产者消费者问题
    • 2.8 读者写者问题
    • 2.9 哲学家就餐问题
    • 2.10 进程通信
    • 2.11 消息缓冲区队列机制
  • 3 线程
    • 3.1 什么是线程
    • 3.2 线程实现
  • 4 处理机调度
    • 4.1 处理机调度概述
    • 4.2 作业调度
    • 4.3 进程调度
    • 4.4 实时调度
  • 5 死锁
    • 5.1 死锁概念及资源分配图
    • 5.2 死锁的必要条件及预防
    • 5.3 死锁避免
    • 5.4 死锁检测和解除
  • 6 存储器管理
    • 6.1 存取器概述及连续分配方式(一)
    • 6.2 动态分区分配及可重定位分区分配
    • 6.3 分页存储管理
    • 6.4 页表结构
    • 6.5 分段及段页式存储管理方式
  • 7 虚拟存储器管理
    • 7.1 虚拟存储技术
    • 7.2 请求分页存储管理
    • 7.3 页面置换算法
    • 7.4 抖动与工作集
    • 7.5 请求分段存储管理
  • 8 磁盘存储器系统
    • 8.1 磁盘存储器的结构
    • 8.2 磁盘调度
    • 8.3 廉价磁盘冗余阵列(RAID)
    • 8.4 提高磁盘I/O的其他方法
    • 8.5 磁盘可靠性技术
  • 9 输入输出系统
    • 9.1 I/O硬件系统
    • 9.2 I/O控制方式
    • 9.3 中断处理程序及设备驱动程序
    • 9.4 设备无关性软件
    • 9.5 缓冲管理
    • 9.6 用户层软件及Spooling
  • 10 文件系统
    • 10.1 文件及逻辑结构
    • 10.2 文件目录结构
    • 10.3 连续分配及链接分配
    • 10.4 索引分配
    • 10.5 空闲空间管理
  • 11 操作系统实验
    • 11.1 实验一  Linux基本命令
    • 11.2 实验二 进程管理
    • 11.3 实验三 进程间通信
    • 11.4 实验四 处理机调度
    • 11.5 实验五 存储管理
    • 11.6 实验六 文件管理
实验五 存储管理

5.1  实验目的

1.加深对操作系统存储管理的理解。

2.能够模拟页面调试算法,加深理解操作系统对内存的高度管理。

5.2  背景知识

1.进先出的算法(FIFO)

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

3.最佳淘汰算法(OPT)

4.最少访问页面算法(LFU)

5.最近最不经常使用算法(NUR)

5.3  实验内容

设计一个虚拟存储区和内存工作区,并使用下列算法计算访问命中率。

1.进先出的算法(FIFO)

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

3.最佳淘汰算法(OPT)

4.最少访问页面算法(LFU)

5.最近最不经常使用算法(NUR)

   命中率=1-页面缺页次数/页地址流长度(缺页率)

请同学们自行设计第2和第3个算法。并比较分析程序结果,

参考例程

首先用srand()和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。相关定义如下:

1.数据结构

(1)页面类型

 typedefstruct{

 int pn,pfn,counter,time;

 }pl_type;

其中pn 为页号,pfn为面框号(块号), counter为一个周期内访问该页面的次数, time为访问时间.

 (2) 页面控制结构

pfc_struct{

      intpn,pfn;

      structpfc_struct *next;

      }

typedef  struct pfc_struct pfc_type;

pfc_type pfc[total_vp],*freepf_head,*busypf_head;

pfc_type *busypf_tail;

 其中pfc[total_vp]定义用户进程虚页控制结构,

*freepf_head为空页面头的指针,

*busypf_head为忙页面头的指针,

*busypf_tail为忙页面尾的指针.

2.函数定义

  (1)void initialize( ):初始化函数,给每个相关的页面赋值.

  (2)void FIFO( ):计算使用FIFO算法时的命中率.

  (3)void LRU( ):计算使用LRU算法时的命中率.

  (4)void OPT( ):计算使用OPT算法时的命中率.

  (5)void LFU( ):计算使用LFU算法时的命中率.

   (6)void NUR( ):计算使用NUR算法时的命中率.

3.变量定义

   (1)int a[total_instruction]: 指令流数据组.

   (2)int page[total_instruction]: 每条指令所属的页号.

   (3)int offset[total_instruction]: 每页装入10条指令后取模运算页号偏移值.

   (4)int total_pf: 用户进程的内存页面数.

   (5)int disaffect: 页面失效次数.

#include<stdio.h>

#include<stdlib.h>

#include <unistd.h>

#defineTRUE 1

#defineFALSE 0

#defineINVALID -1

//#defineNULL 0

#define  total_instruction 320     /*指令流长*/

#define  total_vp 32        /*虚页长*/

#define  clear_period 50      /*清0周期*/

typedefstruct             /*页面结构*/

{

    int pn;     //页号 logic number

    int pfn;    //页面框架号 physical frame number(物理块号)

    int counter;    //计数器

    int time;   //时间

}pl_type;

pl_typepl[total_vp];  /*页面线性结构---指令序列需要使用地址*/

typedefstruct pfc_struct /*页面控制结构,调度算法的控制结构*/

{

    int pn;

    int pfn;

    struct pfc_struct *next;

}pfc_type;

pfc_typepfc[total_vp], *freepf_head, *busypf_head, *busypf_tail;

intdiseffect,  a[total_instruction]; /* a[]为指令序列*/

int page[total_instruction],  offset[total_instruction];/*地址信息*/

intinitialize(int);

intFIFO(int);

intLRU(int);

intLFU(int);

intNUR(int); //not use recently

intOPT(int);

int main()

{

    int s,i,j;

    srand(10*getpid());   /*由于每次运行时进程号不同,故可用来作为初始化随机数队列的“种子”*/

     //s=(float)319*rand()/32767/32767/2+1;  /*正态分布*/

     s=(float)319*rand()/32767+1;

    for(i=0;i<total_instruction;i+=4)    /*产生指令队列*/

    {

        if(s<0||s>319)

        {

            printf("Wheni==%d,Error,s==%d\n",i,s);

            exit(0);

        }

        a[i]=s;       /*任选一指令访问点m*/

        a[i+1]=a[i]+1;   /*顺序执行一条指令*/

        a[i+2]=(float)a[i]*rand( )/32767; /*执行前地址指令m*/

        a[i+3]=a[i+2]+1;                          /*顺序执行一条指令*/

       // s=(float)(318-a[i+2])*rand()/32767/32767/2+a[i+2]+2;

        s=(float)(318-a[i+2])*rand()/32767+a[i+2]+2;

        if((a[i+2]>318)||(s>319))

         printf("a[%d+2],a number which is:%d and s==%d\n",i,a[i+2],s);

 

    }

    for (i=0;i<total_instruction;i++) /*将指令序列变换成页地址流*/

    {

        printf("a[%d]=%d, ",i,a[i]);

        page[i]=a[i]/10;

        offset[i]=a[i]%10;

    }

    for(i=4;i<=32;i++)   /*用户内存工作区从4个页面到32个页面*/

    {

        printf("---%2d pageframes---\n",i);

        FIFO(i);

        LRU(i);

        LFU(i);

        NUR(i);

        OPT(i);

 

    }

    return 0;

}

/*初始化相关数据结构total_pf表示内存的块数 */

 

intinitialize(int total_pf)

{

    int i;

    diseffect=0;

    for(i=0;i<total_vp;i++)

    {

 

        pl[i].pfn=INVALID;       /*置页面控制结构中的页号,页面为空*/

        pl[i].counter=0;         /*页面控制结构中的访问次数为0*/

        pl[i].time=-1;           /*访问的时间*/

    }

 

    for(i=0;i<total_pf-1;i++)   /*建立pfc[i-1]和pfc[i]之间的链接*/

    {

        pfc[i].next=&pfc[i+1];

        pfc[i].pfn=i;

    }

 

    pfc[total_pf-1].next=NULL;

    pfc[total_pf-1].pfn=total_pf-1;

    freepf_head=&pfc[0];         /*空页面队列的头指针为pfc[0]*/

    return 0;

}

intFIFO(int total_pf)              /*先进先出算法total_pf:用户进程的内存页面数*/

{

    int i,j;

    pfc_type *p;                    /*中间变量*/

    initialize(total_pf);         /*初始化相关页面控制用数据结构*/

    busypf_head=busypf_tail=NULL; /*忙页面队列头,队列尾链接*/

    for(i=0;i<total_instruction;i++)

    {

        if(pl[page[i]].pfn==INVALID)   /*页面失效,即缺页*/

        {

            diseffect+=1;                  /*失效(缺页)次数*/

            if(freepf_head==NULL)         /*无空闲页面*/

            {

                p=busypf_head->next;

               pl[busypf_head->pn].pfn=INVALID;

                freepf_head=busypf_head;  /*释放忙页面队列的第一个页面*/

                freepf_head->next=NULL;  /*表明还是缺页*/

                busypf_head=p;

            }

            p=freepf_head->next;

            freepf_head->pn=page[i];

           pl[page[i]].pfn=freepf_head->pfn;

            freepf_head->next=NULL; /*使busy的尾为null*/

            if(busypf_tail==NULL)

            {

               busypf_tail=busypf_head=freepf_head;

            }

            else

            {

               busypf_tail->next=freepf_head;

                busypf_tail=freepf_head;

            }

            freepf_head=p;

        }

    }

   printf("FIFO:%6.4f\n",1-(float)diseffect/320);

    return 0;

}

int LRU(int total_pf)       /*最近最久未使用算法leastrecently used*/

{

   //请同学们自行设计LRU算法

    return 0;

}

int NUR(int  total_pf )                  /*最近未使用算法Not Usedrecently count表示*/

{

    int i,j,dp,cont_flag,old_dp;

    pfc_type *t;

    initialize(total_pf);

    dp=0;

    for(i=0;i<total_instruction;i++)

    {

        if (pl[page[i]].pfn==INVALID)         /*页面失效(缺页)*/

        {

            diseffect++;

            if(freepf_head==NULL)               /*无空闲页面*/

            {

                cont_flag=TRUE;

                old_dp=dp;

                while(cont_flag)

                {

                   if(pl[dp].counter==0&&pl[dp].pfn!=INVALID)

                    cont_flag=FALSE;

                    else

                    {

                        dp++;

                        if(dp==total_vp)

                        dp=0;

                        if(dp==old_dp)

                       for(j=0;j<total_vp;j++)

                        pl[j].counter=0;

                    }

                }

               freepf_head=&pfc[pl[dp].pfn];

                pl[dp].pfn=INVALID;

                freepf_head->next=NULL;

            }

 

        pl[page[i]].pfn=freepf_head->pfn;

 

        freepf_head->pn=page[i];

 

        freepf_head=freepf_head->next;

    }

    else

        pl[page[i]].counter=1;

    if(i%clear_period==0)

        for(j=0;j<total_vp;j++)

            pl[j].counter=0;

    }

   printf("NUR:%6.4f\n",1-(float)diseffect/320);

    return 0;

}

 

int OPT(int total_pf)       /*最佳置换算法*/

{

    //请同学们自行设计最佳置换算法

    return 0;

}

/*该算法时根据已知的预测未知的,leastfrequency  Used是最不经常使用置换法*/

int  LFU(int total_pf)

{

    int i,j,min,minpage;

    pfc_type *t;

    initialize(total_pf);

    for(i=0;i<total_instruction;i++)

    {

        if(pl[page[i]].pfn==INVALID)      /*页面失效*/

        {

            diseffect++;

            if(freepf_head==NULL)          /*无空闲页面*/

            {

                min=32767;

                /*获取counter的使用用频率最小的内存*/

                for(j=0;j<total_vp;j++)

                {

                   if(min>pl[j].counter&&pl[j].pfn!=INVALID)

                    {

                        min=pl[j].counter;

                        minpage=j;

                    }

                }

               freepf_head=&pfc[pl[minpage].pfn];

                pl[minpage].pfn=INVALID;

                pl[minpage].counter=0;

                freepf_head->next=NULL;

            }

           pl[page[i]].pfn=freepf_head->pfn;  //有空闲页面,改为有效

            pl[page[i]].counter++;

           freepf_head=freepf_head->next;     //减少一个free 页面

        }

        else

        {

            pl[page[i]].counter;

           pl[page[i]].counter=pl[page[i]].counter+1;

        }

    }

   printf("LFU:%6.4f\n",1-(float)diseffect/320);

    return 0;

}