• 操作系统-页式虚拟存储器管理系统设计


    (大三下学期开学)操作系统课程设计

    题外话:

    介个系统的算法啊其实很简单很好理解,就是当时自己实践的时候整了好久,各种调bug各种惆怅啊!

    但是此乃100%原创哇!真是老老实实光啃操作系统书自己设计出来的,啥参考都没有

    写完的时候真是太有成就感了(流泪)

    还为此特别手写了算法研究了好久,刚刚翻出笔记本发现自己为了研究地址变换画了个小漫画!(见最下页)

    当时的计划:
    2/27实现的目标:能够根据作业大小为作业分配空间,建立页表。
    2/28实现的目标:完成两种算法的设计与调试
    3/1实现的目标:完善展示界面


    功能分析:

    请求分页式存储管理是基于分页式存储管理的一种虚拟存储器。

    它可以把内存空间划分成尺寸相同、位置固定的块,虚拟地址空间的一页可以装入到内存的任何一块中。

    进程运行时,并不是把整个作业程序全部装到内存中,只装入当前要使用的若干页,此时根据页号查找页表,如果该页不在内存中,没有具体的块号与之对应,出现“缺页”,无法继续运行,此时就要根据页号把该页调入内存使用。

    1、数据结构设计

     1 struct yeb
     2 {
     3     int yebxiang[20];
     4     int flag=0;
     5 } yebb[20];
     6 struct block
     7 {
     8     int num=88;
     9 } bk[30];
    10 int pgclub[2000];//内存物理块初始化为pgcnum
    11 int pgcnum=50;
    12 int bknum=1;
    13 int surplus;//记录剩余物理块数量
    14 int pgnum,pgsize;
    15 int voidornot=0;
    16 int num=0;

    2、功能函数设计与检测

    (1)可以按照作业的大小分配空间,建立页表;

    (2)可以模拟进程的运行过程,如果发生缺页的情况则可以按照一定的页面置换算法选出淘汰页面序列,并展示淘汰页面序列;

    (3)可以展示空间使用情况与页表的情况。

      1 void initpgc()
      2 {
      3     for(int i=0; i<pgcnum; i++)//内存物理块的初始化
      4     {
      5         pgclub[i]=0;
      6     }
      7     num=pgcnum/bknum;
      8     cout<<" 内存物理块已经成功初始化!本系统共有"<<num<<"个可用物理块,每个块的大小为"<<bknum<<"KB!(^_^)"<<endl;
      9     cout<<"☆---------------------------------------------------------------------------☆"<<endl;
     10 }
     11 void checksurplus()//检查可用空间
     12 {
     13     surplus=0;
     14     for(int i=0; i<pgcnum; i++)
     15     {
     16         if(pgclub[i]==0)surplus++;
     17     }
     18 }
     19 void showsurplus()
     20 {
     21     cout<<"现在输出物理块的存储信息:"<<endl;
     22     cout<<"※--------------------※"<<endl;
     23     for(int i=0; i<num; i++)
     24     {
     25         if(i==0||(i%10)==0) cout<<"| ";
     26         cout<<pgclub[i]<<" ";
     27         if((i+1)%10==0) cout<<"|"<<endl;//每十个换行
     28     }
     29     cout<<"※--------------------※"<<endl<<endl;
     30 }
     31 void showyebiao(int pgnum)
     32 {
     33     cout<<"现在输出作业"<<pgnum<<"的页表:"<<endl;
     34     int last=0;
     35     cout<<"*------※------*"<<endl;
     36     cout<<"| 页号 | 块号  |"<<endl;
     37     for(int i=0;; i++,last++)
     38         if(yebb[pgnum].yebxiang[i]==88) break;
     39     for(int i=0; i<last; i++)
     40     {
     41 
     42         cout<<"|  "<<i<<"   |   "<<yebb[pgnum].yebxiang[i]<<"   |"<<endl;
     43     }
     44 
     45     cout<<"*------※------*"<<endl;
     46 }
     47 void creathomework()
     48 {
     49 
     50     cout<<"输入新建立的作业号(0~19)与大小(单位:KB)"<<endl;
     51     cin>>pgnum>>pgsize;
     52     int pgsize2=pgsize;
     53     int danwei=pgsize/bknum;
     54     int pgnum2=pgnum;
     55     checksurplus();//检查可用空间
     56     if(danwei>surplus)
     57         cout<<"空间不足。"<<endl;
     58     else
     59     {
     60         for(int i=0; i<20; i++)
     61             yebb[pgnum].yebxiang[i]=88;//预用初始化
     62         int yebnum=0;
     63         cout<<"将为你分配"<<danwei<<"个物理块!"<<endl;
     64         cout<<"请顺序输入对应存储的物理块号:"<<endl;
     65         while(danwei)
     66         {
     67             int anum;
     68             //计数变量
     69             cin>>anum;
     70 
     71             if(!pgclub[anum])
     72             {
     73                 pgclub[anum]=pgnum;//表示被占用
     74                 danwei--;
     75                 yebb[pgnum].yebxiang[yebnum]=anum;
     76                 yebnum++;
     77                 //存储检查(调试)
     78                 //  cout<<yebnum<<" "<<anum<<endl;
     79                 // cout<<yebb[pgnum].yebxiang[yebnum-1]<<endl;
     80             }
     81             else cout<<"该物理块已经被占用。请重新输入其它物理块号(T_T)"<<endl;
     82         }
     83         voidornot=1;
     84         yebb[pgnum].flag=1;
     85         showsurplus();
     86         showyebiao(pgnum);
     87     }
     88 }
     89 int check()
     90 {
     91     if(voidornot==0) return 1;
     92     else return 0;
     93 }
     94 
     95 void createjc()
     96 {
     97     int flag=check();
     98     if(flag)
     99     {
    100         cout<<"作业都没有,跑什么跑"<<endl;
    101     }
    102     else
    103     {
    104         cout<<"请选择一种页面置换算法。"<<endl;
    105         cout<<"1、FIFO"<<endl;
    106         cout<<"2、LRU"<<endl;
    107         int lob;
    108         cin>>lob;
    109         if(lob==1)
    110         {
    111             cout<<"你要跑的进程是哪家的?"<<endl;
    112             int win;
    113             cin>>win;
    114             if(!yebb[win].flag)
    115                 cout<<"没有你这个儿子进程!"<<endl;
    116             else
    117             {
    118                 int last=0;
    119                 for(int i=0;; i++,last++)
    120                     if(yebb[win].yebxiang[i]==88) break;
    121                 cout<<"请输入15个由作业"<<win<<"的物理块号所组成的序列:"<<endl;
    122                 for(int i=0; i<last; i++)
    123                 {
    124                     cout<<yebb[win].yebxiang[i];
    125                     if(!(i==(last-1))) cout<<"";
    126                     else cout<<endl;
    127                 }
    128                 int number[15];
    129                 for(int i=0; i<15; i++)
    130                 {
    131                     cin>>number[i];
    132                 }
    133                 int error=0;
    134                 cout<<"你想要给它分配多少个物理块?(1~10)以内";
    135                 int X;
    136                 cin>>X;
    137                 int countt=0;
    138                 for(int i=0; i<30; i++)
    139                 {
    140                     bk[i].num=88;
    141                 }
    142                 for(int i=0; i<15; i++)
    143                 {
    144                     int flag1=0;
    145                     for(int j=0; j<X; j++)
    146                     {
    147                         if(number[i]==bk[j].num)
    148                         {
    149                             cout<<number[i]<<endl;
    150                             flag1=1;
    151                         }
    152                     }
    153                     if(!flag1)
    154                     {
    155                         error++;
    156                         //cout<<"error="<<error<<endl;
    157                         if(error<=X)//未满
    158                         {
    159                             bk[error-1].num=number[i];
    160                             cout<<number[i]<<"|";
    161                             for(int k=0; k<i+1; k++)
    162                                 if(bk[k].num!=88)
    163                                     cout<<bk[k].num<<" ";
    164                             cout<<endl;
    165                         }
    166                         else //已经满,要置换
    167                         {
    168                             bk[(error-1)%X].num=number[i];
    169                             cout<<number[i]<<"|";
    170                             for(int k=0; k<X; k++)
    171                                 if(bk[k].num!=88)
    172                                     cout<<bk[k].num<<" ";
    173                             cout<<endl;
    174                         }
    175                     }
    176                 }
    177                 cout<<"使用FIFO算法在分配的物理块为"<<X<<"个情况下,缺页次数是"<<error<<"次。命中率为"<<(1-((double)error/15))*100<<"%!"<<endl;
    178             }
    179         }
    180         else
    181         {
    182             cout<<"你要跑的进程是哪家的?"<<endl;
    183             int win;
    184             cin>>win;
    185             if(!yebb[win].flag)
    186                 cout<<"没有你这个儿子"<<endl;
    187             else
    188             {
    189                 int last=0,flag3=0;
    190                 for(int i=0;; i++,last++)
    191                     if(yebb[win].yebxiang[i]==88) break;
    192                 cout<<"请输入15个由作业"<<win<<"的物理块号所组成的序列:"<<endl;
    193                 for(int i=0; i<last; i++)
    194                 {
    195                     cout<<yebb[win].yebxiang[i];
    196                     if(!(i==(last-1))) cout<<"";
    197                     else cout<<endl;
    198                 }
    199                 int number[15];
    200                 for(int i=0; i<15; i++)
    201                 {
    202                     cin>>number[i];
    203                 }
    204                 int error=0;
    205                 cout<<"你想要给它分配多少个物理块?(1~10)以内";
    206                 int X,flag2=1;
    207                 int topnumber=0;
    208                 cin>>X;
    209                 for(int i=0; i<30; i++)//物理块初始化
    210                 {
    211                     bk[i].num=88;
    212                 }
    213                 for(int i=0; i<15; i++)
    214                 {
    215                     int flag=0;
    216                     for(int o=0; o<X; o++)//查询栈中是否存在要访问的页面
    217                     {
    218                         if(number[i]==bk[o].num)//如果访问的页面在栈中
    219                         {
    220                             //int flag4=0;
    221                             if(number[i-1]!=number[i])
    222                             {
    223                                 for(int p=o; p<topnumber; p++) //栈元素向后推,将最近访问的页号存到栈顶元素。
    224                                 {
    225                                     bk[p].num=bk[p+1].num;
    226                                 }
    227                                 bk[topnumber-1].num=number[i];
    228                             }
    229 
    230                             cout<<number[i]<<"|";//输出栈的情况
    231                             for(int j=0; j<10; j++)
    232                                 if(bk[j].num!=88)
    233                                     cout<<bk[j].num<<" ";
    234                             //cout<<"top"<<topnumber;
    235                             cout<<endl;
    236                             flag=1;
    237                             break;
    238                         }
    239                     }
    240                     if(!flag)//缺页
    241                     {
    242 
    243                         //cout<<topnumber<<endl;
    244                         error++;
    245                         if(!flag3)
    246                         {
    247                             if(topnumber<X)//如果此时栈未满
    248                             {
    249                                 topnumber++;
    250                                 bk[topnumber-1].num=number[i];
    251                             }
    252                             else if(topnumber==X)//此时栈已经满了
    253                             {
    254                                 //topnumber=X-1;
    255                                 flag3=1;//表示满了
    256                             }
    257                         }
    258                         if(flag3) //栈满了,首先将栈顶以下的都向下移,再将新的页面放到栈顶,topnumber=X
    259                         {
    260                             for(int m=0; m<X-1; m++)
    261                             {
    262                                 bk[m].num=bk[m+1].num;
    263                             }
    264                             bk[X-1].num=number[i];
    265                         }
    266                         cout<<number[i]<<"|";//输出
    267                         for(int k=0; k<10; k++)
    268                         {
    269                             if(bk[k].num!=88)
    270                                 cout<<bk[k].num<<" ";
    271                         }
    272                         //cout<<"top"<<topnumber;
    273                         cout<<"缺页(T_T)";
    274                         cout<<endl;
    275                     }
    276 
    277                 }
    278                 cout<<"使用LRU算法在分配的物理块为"<<X<<"个情况下,缺页次数是"<<error<<"次。命中率为"<<(1-((double)error/15))*100<<"%!"<<endl;
    279             }
    280 
    281 
    282         }
    283     }
    284 
    285 }
    286 
    287 void menu1()
    288 {
    289     int c;
    290 
    291     cout<<"请设定内存块总大小以及每一个页面的大小。"<<endl;
    292     while(1)
    293     {
    294         cin>>pgcnum>>bknum;
    295         if(pgcnum%bknum!=0)
    296             cout<<"你输入的数不合法,请重新输入。"<<endl;
    297         else break;
    298     }
    299 
    300 
    301     initpgc();//内存物理块的初始化
    302     while(1)
    303     {
    304         cout<<"                 欢迎来到小系统,请输入数字执行你想要执行的操作。"<<endl;
    305         cout<<"☆---------------------------------------------------------------------------☆"<<endl;
    306         cout<<"                             1、我要写作业"<<endl<<endl;
    307         cout<<"                             2、我要跑进程"<<endl<<endl;
    308         cout<<"                             3、查看物理块的存储信息"<<endl<<endl;
    309         cout<<"                             9、我走了"<<endl;
    310         cout<<"☆---------------------------------------------------------------------------☆"<<endl;
    311         int choose;
    312         cin>>choose;
    313         if(choose==1)
    314         {
    315 
    316             creathomework();
    317         }
    318         else if(choose==2)
    319         {
    320             createjc();
    321         }
    322         else if(choose==3)
    323         {
    324             showsurplus();
    325         }
    326         else if(choose==9)
    327             break;
    328         else cout<<"非法参数,重新输入,好吗!"<<endl;
    329     }
    330     cout<<"byebye!"<<endl;
    331 
    332 }
    333 int main()
    334 {
    335     //int start=0;
    336     menu1();
    337     return 0;
    338 }

    3、附系统运行截图


    附图:当时为研究地址变换画了个小漫画,虽然……最后这个代码里没具体实现地址变换

  • 相关阅读:
    lambda 和 iterable
    使用Jenkins部署Python项目
    python下selenium自动化测试自我实践
    【其它】数学学科编码
    【其它】音阶中的数学
    【数理统计基础】 06
    【数理统计基础】 05
    【数理统计基础】 04
    【数理统计基础】 03
    【数理统计基础】 02
  • 原文地址:https://www.cnblogs.com/AKsnoopy/p/7282913.html
Copyright © 2020-2023  润新知