(大三下学期开学)操作系统课程设计
题外话:
介个系统的算法啊其实很简单很好理解,就是当时自己实践的时候整了好久,各种调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、附系统运行截图
附图:当时为研究地址变换画了个小漫画,虽然……最后这个代码里没具体实现地址变换