操作系统实验报告---主存分配与回收(最佳适应算法)
程序员文章站
2022-10-19 13:35:59
动态分区存储管理方式主存的分配与回收 16网络工程二班 孙书魁 目的: 1,了解动态分区分配中,使用的数据结构和算法 2,深入了解动态分区存储管理方式,主存分配与回收的实现 3,进一步加深动态分区存储管理方式及其实现过程的了解 具体实现: 确定主存分配表,然后采用最佳适应算法,完成完成主存分配和回收 ......
动态分区存储管理方式主存的分配与回收
16网络工程二班 孙书魁
目的:
1,了解动态分区分配中,使用的数据结构和算法
2,深入了解动态分区存储管理方式,主存分配与回收的实现
3,进一步加深动态分区存储管理方式及其实现过程的了解
具体实现:
确定主存分配表,然后采用最佳适应算法,完成完成主存分配和回收,最后编写主函数,进行主函数进行测试。
具体实现:
主存分配之前的之态,主存分配过程中的状态,回收后的状态
1 #include <stdio.h> 2 #include <string.h> 3 #define MAX 600 //设置总内存大小为512k 4 5 struct partition { 6 char pn[10];//分区名字 7 int begin;//起始地址 8 int size;//分区大小 9 int end;//结束地址 10 char status;//分区状态 11 }; 12 struct partition part[MAX]; 13 int p = 0; //标记上次扫描结束处 14 15 void Init()//初始化分区地址、大小以及状态 16 { 17 int i; 18 for ( i = 0; i < MAX; i++ ) 19 part[i].status = '-'; 20 strcpy( part[0].pn, "SYSTEM" ); 21 part[0].begin = 0; 22 part[0].size = 100; 23 part[0].status = 'u'; 24 25 strcpy( part[1].pn, "-----" ); 26 part[1].begin = 100; 27 part[1].size = 100; 28 part[1].status = 'f'; 29 strcpy( part[2].pn, "A" ); 30 part[2].begin = 200; 31 part[2].size = 50; 32 part[2].status = 'u'; 33 strcpy( part[3].pn, "-----" ); 34 part[3].begin = 250; 35 part[3].size = 50; 36 part[3].status = 'f'; 37 strcpy( part[4].pn, "B" ); 38 part[4].begin = 300; 39 part[4].size = 100; 40 part[4].status = 'u'; 41 strcpy( part[5].pn, "-----" ); 42 part[5].begin = 400; 43 part[5].size = 200; 44 part[5].status = 'f'; 45 for ( i = 0; i < MAX; i++ ) 46 part[i].end = part[i].begin + part[i].size-1; 47 } 48 49 50 void Output( int i ) //以行的形式输出结构体的数据 51 { 52 printf( "\t%s", part[i].pn ); 53 printf( "\t%d", part[i].begin ); 54 printf( "\t%d", part[i].size ); 55 printf( "\t%d", part[i].end ); 56 printf( "\t%c", part[i].status ); 57 } 58 59 60 void display() //显示分区 61 { 62 int i; 63 int n; //用n来记录分区的个数 64 printf("\n"); 65 printf( "\n 已分配分区表Used:" ); 66 printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" ); 67 printf("\n"); 68 n = 1; 69 for ( i = 0; i < MAX; i++ ) 70 { 71 if ( part[i].status == '-' ) 72 break; 73 if ( part[i].status == 'u' ) 74 { 75 printf( "\n\tNo.%d", n ); 76 Output( i ); 77 n++;// 记录已分配使用的分区个数 78 } 79 } 80 printf("\n"); 81 printf( "\n 空闲分区表Free:" ); 82 printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" ); 83 printf("\n"); 84 n = 1; 85 for ( i = 0; i < MAX; i++ ) 86 { 87 if ( part[i].status == '-' ) 88 break; 89 if ( part[i].status == 'f' ) 90 { 91 printf( "\n\tNo.%d", n ); 92 Output( i ); 93 n++; //记录空闲分区的个数 94 } 95 } 96 // printf( "\n" ); 97 printf("\n"); 98 printf( "\n 内存使用情况,按起始址增长的排:" ); 99 //printf( "\n printf sorted by address:" ); 100 printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" ); 101 printf("\n"); 102 n = 1; 103 for ( i = 0; i < MAX; i++ ) 104 { 105 if ( part[i].status == '-' ) 106 break; 107 printf( "\n\tNo.%d", n ); 108 Output( i ); 109 n++;//记录已分配分区以及空闲分区之和的总个数 110 } 111 getch(); 112 } 113 114 void Fit( int a, char workName[], int workSize ) //新作业把一个分区分配成两个分区:已使用分区和空闲分区 115 { 116 int i; 117 for ( i = MAX; i > a + 1; i-- ) 118 { 119 //通过逆向遍历,把在a地址后的所有分区往后退一个分区,目的在于增加一个分区 120 if ( part[i - 1].status == '-' ) 121 continue; 122 part[i]=part[i-1]; 123 } 124 strcpy( part[a + 1].pn, "-----" ); 125 part[a + 1].begin = part[a].begin + workSize; 126 part[a + 1].size = part[a].size - workSize; 127 part[a + 1].end = part[a].end-1; 128 part[a + 1].status = 'f'; 129 strcpy( part[a].pn, workName ); 130 part[a].size = workSize; 131 part[a].end = part[a].begin + part[a].size-1; 132 part[a].status = 'u'; 133 } 134 void fenpei() // 分配 135 { 136 int i; 137 int a; 138 int workSize; 139 char workName[10]; 140 int pFree; 141 printf( "\n请输入作业名称:" ); 142 scanf( "%s", &workName ); 143 for(i=0;i<MAX;i++) 144 { 145 if(!strcmp(part[i].pn,workName))//判断作业名称是否已经存在 146 { 147 printf("\n作业已经存在,不必再次分配!\n"); 148 return; 149 } 150 } 151 printf( "请输入作业大小(k):" ); 152 scanf( "%d", &workSize ); 153 for ( i = 0; i < MAX; i++ )//通过循环在空闲区找是否有适合区间存储作业 154 { 155 if ( part[i].status == 'f' && part[i].size >= workSize ) 156 { 157 pFree = i; 158 break; 159 } 160 } 161 if ( i == MAX ) 162 { 163 printf( "\n该作业大小超出最大可分配空间" ); 164 getch(); 165 return; 166 } 167 168 for ( i = 0; i < MAX; i++ )//最佳适应算法 169 if ( part[i].status == 'f' && part[i].size >= workSize ) 170 if ( part[pFree].size > part[i].size ) 171 pFree = i;//通过遍历所有区间,每次都找到最小空闲分区进行分配 172 Fit( pFree, workName, workSize ); 173 printf( "\n分配成功!" ); 174 getch(); 175 } 176 void hebing() //合并连续的空闲分区 177 { 178 int i = 0; 179 while ( i != MAX - 1 ) 180 { 181 for ( i = 0; i < MAX - 1; i++ ) 182 { 183 if ( part[i].status == 'f' ) 184 if ( part[i + 1].status == 'f' ) 185 { 186 part[i].size = part[i].size + part[i + 1].size; 187 part[i].end = part[i].begin + part[i].size-1; 188 i++; 189 for ( i; i < MAX - 1; i++ ) 190 { 191 if ( part[i + 1].status == '-' ) 192 { 193 part[i].status = '-'; 194 break; 195 196 } 197 198 part[i]=part[i+1]; 199 } 200 part[MAX - 1].status = '-'; 201 break; 202 } 203 } 204 } 205 } 206 207 208 void huishou() // 回收分区 209 { 210 int i; 211 int number; 212 int n=0; 213 printf( "\n请输入回收的分区号:" ); 214 scanf( "%d", &number ); 215 if ( number == 1 ) 216 { 217 printf( "\n系统分区无法回收" ); 218 return; 219 } 220 for ( i = 0; i < MAX; i++ )//通过循环查找要回收的已使用分区区号 221 { 222 if ( part[i].status == 'u' ) 223 { 224 n++; 225 if ( n == number ) 226 { 227 strcpy( part[i].pn, "-----" ); 228 part[i].status = 'f'; 229 } 230 } 231 } 232 if ( i == MAX - 1 ) 233 { 234 printf( "\n找不到分区" ); 235 return; 236 } 237 hebing();//合并连续的空闲分区 238 printf( "\n回收成功!" ); 239 getch(); 240 } 241 242 243 void main() 244 { 245 int selection; 246 Init(); 247 printf( "初始化完成,设内存容量%dk", MAX ); 248 printf( "\n系统文件从低址存储,占%dk", part[0].size ); 249 while ( 1 ) 250 { 251 printf( "\n----------选择----------" ); 252 printf( "\n| 0、退出系统 |" ); 253 printf( "\n| 1、显示分区 |" ); 254 printf( "\n| 2、分配分区 |" ); 255 printf( "\n| 3、回收分区 |" ); 256 printf( "\n------------------------"); 257 printf( "\n请选择 > " ); 258 while ( 1 ) 259 { 260 scanf( "%d", &selection ); 261 if ( selection == 0 ||selection == 1 || selection == 2 || selection == 3 ) 262 break; 263 printf( "输入错误,请重新输入:" ); 264 } 265 switch ( selection ) 266 { 267 case 0: 268 exit(0); //退出系统 269 break; 270 case 1: 271 display(); //显示分区 272 break; 273 case 2: 274 fenpei(); //分配作业 275 break; 276 case 3: 277 huishou(); //回收分区 278 break; 279 default: 280 break; 281 } 282 } 283 }