zoukankan      html  css  js  c++  java
  • 实验五 操作系统之存储管理

    网络工程专业   姓名:蔡利聪  学号:201306114117

    一、目的和要求

    1. 实验目的

        连续内存分配方式会形成许多“碎片”,虽然可以通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。如果允许将一个进程直接分散地装入到许多不相邻接的分区中,则无需再进行“紧凑”。基于这一思想而产生了离散分配方式。

    如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。  

    在分页存储管理方式中,如果不具备页面兑换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入内存后方能运行。

    本实验通过程序模拟操作系统的基本分页存储管理方式,进一步理解这一内存分配方式的原理和特点,加深对理论知识的掌握。

    2.实验要求

     (1)用C语言或Java语言编写程序模拟操作系统对内存的基本分页存储管理方式。  

       (2)程序要能正确对“内存”进行“分配”和“回收”,能接受用户的输入,显示内存的分配情况,并有一定的容错能力。 

    二、实验内容 

       本实验假定内存空间已经按块划分,目标程序无需关心内存块大小等底层细节,只需按算法对内存块进行分配即可。程序应该实现以下功能:

      1、内存初始化。假定内存块共有N个,初始化后的内存空间应该有一部分已经被使用,这可以用随机数或程序内部的其他算法完成。

      2、程序应该能接受用户输入的进程信息,并为之分配内存,返回分配结果(成功或失败),注意,此处应该考虑到不合法的输入并进行相应处理。

      3、程序能回收用户指定的进程所占用的内存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。

      4、能直观合理地显示内存分配情况。

      5、程序界面友好,便于操作和查看运行结果。 

    三、实验方法、步骤及结果测试

    1. 源程序名:存储管理.cpp

    可执行程序名:存储管理.exe

    2. 原理分析

        (1)编写该程序首先要定义一个一定空间大小的内存块100,即申请空闲区空间最大值,并且要初始化内存状态标志数组block[i],以及初始化存放进程的数组process[i][j],保证内存大小足够分配给相应的进程使用。

    (2)通过设置菜单项,达到友好的访问内存的请求界面,把创建进程向内存获取空间,把结束进程让内存回收空间分为两个程序段函数,各自独立完成相应的功能,最后通过主函数直接调用创建进程和结束进程这两个函数。

    3. 主要程序段及其解释:

      1 #include <stdio.h> 
      2 #include <windows.h> 
      3 #define N 100        // 共有100个内存块
      4    int process[N][N+1]; // 存放每个进程的页表
      5    int block[N];        // 内存块状态标志数组,0:空闲,1:使用
      6    int blockCount;      // 记录当前内存剩余空间
      7    int processCount;    // 记录当前进程数
      8    bool flag = true;
      9  
     10 void init();
     11 void output(); 
     12 bool createProcess();
     13 bool endProcess();
     14 void menu(); 
     15 
     16 //主函数  
     17 void main() 
     18 { 
     19     init();  
     20     menu(); 
     21 }
     22 
     23 void init() 
     24 {
     25     int i, j;   
     26     for (i=0; i<N; i++)// 初始化内存状态标志数组
     27         block[i] = 0;
     28     for (i=0; i<20; i++)
     29         block[rand()%(N-1)] = 1; 
     30     blockCount = 0; 
     31     for (i=0; i<N; i++) 
     32         if (block[i] == 0) 
     33              blockCount++; 
     34 // 初始化存放进程的数组 
     35     for (i=0; i<N; i++)
     36     {  
     37          process[i][0] = 0;  
     38          for (j=1; j<N; j++)   
     39              process[i][j] = -1; 
     40     }  
     41     processCount = 0; 
     42     printf("初始化结果如下:"); 
     43     output();  
     44     flag = false; 
     45 }  
     46 void output() 
     47 { 
     48     printf("
    内存总量:%d 块, 已用空间:%d 块, 剩余空间:%d 块, 进程总数:%d 个
    ", N, N-blockCount, blockCount, processCount); 
     49     if (flag && blockCount < N)
     50     {   
     51         printf("已使用的内存块(%d):
    ", N-blockCount);  
     52         for (int k=0,count=0; k<N; k++)   
     53         {  
     54              if (block[k] == 1)   
     55                   printf("%2d ", k, ++count);   
     56     
     57              if (count == 15)    
     58              {   
     59                   putchar('
    ');    
     60                   count = 0;    
     61              }   
     62         } 
     63         putchar('
    '); 
     64     }
     65     // 输出各进程占用内存详细情况    
     66     if(processCount>0)
     67     {
     68 
     69         printf("内存详细使用情况如下:
    ");  
     70         for (int i=0; i<N; i++)   
     71         {   
     72              if (process[i][0] > 0)    
     73              {    
     74                   printf("进程号:%d 
    占用内存块(%2d):", i, process[i][0]);   
     75                   for (int j=1,count=0; j<=process[i][0]; j++)     
     76                   {
     77                        printf("%2d ", process[i][j], count++);  
     78                        if (count == 15)     
     79                        {     
     80                             putchar('
    ');      
     81                             printf("                ");       
     82                             count = 0;      
     83                        }     
     84                   }   
     85                   putchar('
    ');   
     86              }  
     87         } 
     88     } 
     89     else   
     90         printf("当前内存无进程!
    ");  
     91                                // 输出空闲内存块 
     92     putchar('
    '); 
     93 }  
     94 bool createProcess() 
     95 {  
     96     int pid, pages, k = 0; 
     97 loop:printf("请输入进程号(小于%d)和所需页面数:", N);  
     98     scanf("%d%d", &pid, &pages); 
     99     if (pid > 99)  
    100     {  
    101         printf("错误!进程号过大!
    ");  
    102         goto loop;  
    103     } 
    104     if (pages > blockCount) 
    105         return false;  
    106     blockCount -= pages;  
    107     process[pid][0] = pages; 
    108     for (int i=1; i<=pages; i++)    
    109     {   
    110         while (block[k]==1 && k<100)   
    111             k++; 
    112         process[pid][i] = k;  
    113         block[k] = 1;  
    114         k++;  
    115     } 
    116     processCount++; 
    117     return true; 
    118 }  
    119 bool endProcess() 
    120 { 
    121     int pid, pages; 
    122     if (processCount < 1)  
    123     {   
    124         printf("当前内存没有进程!
    
    ");  
    125         return false;  
    126     } 
    127     printf("当前内存中的进程有 %d 个, 进程号为:", processCount); 
    128     for (int i=0; i<N; i++)  
    129         if (process[i][0] > 0)  
    130              printf("%2d ", i);  
    131     putchar('
    ');
    132     printf("请输入您要结束的进程号(小于%d):", N);  
    133     scanf("%d", &pid); 
    134     pages = process[pid][0]; 
    135     if (pages == 0) 
    136     { 
    137          printf("对不起!该进程不存在!
    "); 
    138          return false; 
    139     } 
    140     for (int j=1; j<pages; j++) 
    141     { 
    142          block[process[pid][j]] = 0;  
    143          process[pid][j] = -1; 
    144     } 
    145     process[pid][0] = 0; 
    146     processCount--; 
    147     blockCount += pages;
    148     return true; 
    149 }  
    150 void menu() 
    151 { 
    152     int choice; 
    153     while (true)  
    154     {  
    155          printf("操作菜单:
    ");  
    156          printf(" 1 --> 创建进程
     2 --> 结束进程
     3 --> 查看内存
     0 --> 退出程序
    "); 
    157          printf("请输入您要进行的操作:");   
    158          scanf("%d", &choice);  
    159          switch (choice)  
    160          {  
    161           case 1:   
    162               if (createProcess())    
    163                   printf("创建新进程成功!
    
    ");    
    164               else    
    165                   printf("抱歉!内存空间不足,创建新进程失败!
    
    ");   
    166               break;  
    167           case 2:   
    168               if (endProcess())    
    169                   printf("进程已结束!
    
    ");   
    170               else    
    171                   printf("进程结束失败!
    
    ");   
    172               break;  
    173           case 3:   
    174               output();  
    175               break;  
    176           case 0: 
    177               return ;  
    178           default:  
    179               printf("对不起!您的选择有误!请重新选择!
    
    ");   
    180          }  
    181     } 
    182 }

    4. 运行结果



    默认创建的内存为100块,其中系统占用18块,剩余82块可供创建进程使用,当创建进程号为1,页面数为3的进程后,内存立刻为进程分配了3块空间0,1,2;当进程结束时,内存回收进程号1的空间,本次实验结果符合预期。

    四、实验总结

    本次实验是有关存储管理空间分配的算法的实现,实验内容相对之前的进程调度稍微简洁些,只需要通过内存空间大小,定义数组页表,然后进程请求空间块或释放空间块只需通过数组页表进行访问,然后内存提供相应的内存分配和回收。

    虽然步骤比较清晰,对于二维数组使用的知识存在欠缺,写相关的代码比较不熟练,中间遇到很多困难,比如二维数组的调度,还有一些基本的C语言的语法结构掌握不熟练,而且对算法与与程序之间的思维不清晰,导致在写程序中出现较多问题,然后通过查找课本,上网搜寻资料,询问同学进行帮助解答,最后得到基本的实验程序。

  • 相关阅读:
    机械学习--5
    机械学习--4
    机械学习--3
    机械学习--2
    机器学习--1
    编译原理 作业十五
    编译原理 作业十四
    编译原理 作业十二
    编译原理 作业十一
    编译原理 作业十
  • 原文地址:https://www.cnblogs.com/clcbk/p/4599140.html
Copyright © 2011-2022 走看看