1.實作效果


2.實作源代碼
1 #include<iostream> 2 #include<process.h> 3 #include<stdlib.h> 4 #include<ctime> 5 #include<conio.h> 6 #include<stdio.h> 7 #include<string.h> 8 using namespace std; 9 10 #define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|\n")/*表格控制*/ 11 #define bsize 4 //物理塊大小 12 #define psize 16 //行程大小 13 void chushihua();//初始化函式 14 void ymzh(); 15 void yemianzhihuan (); 16 void changeaddr(struct Page p[], int logaddr); 17 void dizhizhuanhuan(); 18 void menu(); 19 int wang(); 20 21 int yemianliu[32]={0};//全域變數陣列,地址流 22 int p; 23 struct Page { 24 int pno;//頁號 25 int flag;//標志位 26 int cno;//主存號 27 int modf;//修改位 28 int addr;//外存地址 29 }Page; //全域變數p是一共有多少地址流 30 31 typedef struct pagel 32 { 33 int num; /*記錄頁面號*/ 34 int time; /*記錄調入記憶體時間*/ 35 }Pagel; /*頁面邏輯結構,方便演算法實作*/ 36 37 Pagel b[bsize]; /*記憶體單元數*/ 38 int c[bsize][psize];/*保存記憶體當前的狀態:緩沖區*/ 39 int queue[100];/*記錄調入佇列*/ 40 int k;/*調入佇列計數變數*/ 41 int phb[bsize]={0};//物理塊標號 42 int pro[psize]={0};//行程式列號 43 int flag[bsize]={0};//行程等待次數(存放最久未被使用的行程標志)*/ 44 int i=0,j=0;//i表示行程式列號,j表示物理塊號*/ 45 int m =-1,n =-1;//物理塊空閑和行程是否相同判斷標志*/ 46 int mmax=-1, maxflag=0;//標記替換物理塊行程下標*/ 47 int count =0; //統計頁面缺頁次數 48 49 void chushihua() //初始化函式 50 { 51 int t; 52 srand(time(0));//隨機產生指令序列 53 p=12+rand()%32; 54 cout<<"地址流序列:"; 55 cout<<endl; 56 for(i=0; i<p; i++) 57 { 58 t=1+rand()%9; 59 yemianliu[i]=t;//將隨機產生的指令數存入頁面流 60 } 61 for (i=p-1;i>=0;i--) 62 { 63 cout<<yemianliu[i]<<" "; 64 } 65 cout<<endl; 66 } 67 void ymzh() 68 { 69 chushihua(); 70 yemianzhihuan(); 71 } 72 73 void yemianzhihuan() 74 { 75 int a; 76 printf("----------------------------------\n"); 77 printf("☆☆歡迎使用分頁模擬實驗系統☆☆\n"); 78 printf("----------------------------------"); 79 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 80 printf("☆☆1.進入硬體地址變換演算法 ☆☆\n"); 81 printf("☆☆------------------------☆☆\n"); 82 printf("☆☆2.進入頁面置換演算法 ☆☆\n"); 83 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 84 printf("請輸入您的選擇:"); 85 switch(a) 86 { 87 case 1: 88 ymzh(); 89 break; 90 case 2: 91 wang(); 92 break; 93 default: 94 cout<<"輸入有誤,請重新輸入!"<<endl; 95 break; 96 } 97 } 98 99 void changeaddr(struct Page p[], int logaddr){//地址變換 100 int j=logaddr/64;//對應的塊號 101 int k=logaddr%64; //對應的偏移量 102 int flag=0; 103 int addr; 104 for(int i=0;i<8;i++) 105 { 106 if(p[i].pno==j)//找到對應的頁號 107 { 108 if(p[i].flag==1)//頁面標志為1 109 { 110 addr=p[i].cno*64+k; 111 cout<<"物理地址為:"<<addr<<endl; 112 cout<<"詳細資訊:"<<"\t頁面號:"<<p[i].pno<<"\t 主存號:"<<p[i].cno<<"\t偏移量:"<<k<<endl; 113 flag=1; 114 break; 115 } 116 } 117 } 118 119 if(flag==0) 120 cout<<"該頁不在主存,產生缺頁中斷"<<endl; 121 } 122 123 void dizhizhuanhuan() 124 { 125 int a; 126 int ins;//指令邏輯地址 127 struct Page p[8]; 128 p[0].pno=0;p[0].flag=1;p[0].cno=5;p[0].modf=1;p[0].addr=011; 129 p[1].pno=1;p[1].flag=1;p[1].cno=8;p[1].modf=1;p[1].addr=012; 130 p[2].pno=2;p[2].flag=1;p[2].cno=9;p[2].modf=0;p[2].addr=013; 131 p[3].pno=3;p[3].flag=1;p[3].cno=10;p[3].modf=0;p[3].addr=015; 132 p[4].pno=4;p[4].flag=0;p[4].addr=017; 133 p[5].pno=5;p[5].flag=0;p[5].addr=025; 134 p[6].pno=6;p[6].flag=0;p[6].addr=212; 135 p[7].pno=7;p[7].flag=0;p[7].addr=213; 136 printf("\t\t\t--------------------------------\n"); 137 printf("\t\t\t☆☆歡迎使用分頁模擬實驗系統☆☆\n"); 138 printf("\t\t\t---------------------------------\n"); 139 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 140 printf("\t\t\t☆☆1.輸入指令 ☆☆\n"); 141 printf("\t\t\t☆☆------------------------☆☆\n"); 142 printf("\t\t\t☆☆2.進入頁面置換演算法 ☆☆\n"); 143 printf("\t\t\t☆☆------------------------☆☆\n"); 144 printf("\t\t\t☆☆0.EXIT ☆☆\n"); 145 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 146 while(a!=0) 147 { 148 cout<<endl<<"請輸入您的選擇:"; 149 cin>>a; 150 151 cout<<"頁號"<<"標記位"<<"外存地址"<<"主存號"<<endl; 152 for(int i=0;i<8;i++) 153 { 154 cout<<p[i].pno<<"\t"<<p[i].flag<<"\t"<<p[i].addr<<"\t"; 155 if(p[i].flag) 156 cout<<p[i].cno; 157 cout<<endl; 158 } 159 160 switch(a) 161 { 162 case 0:printf("\t\t\t再見!\t\t\t\n"); break; 163 case 1: 164 cout<<"請輸入指令的邏輯地址:"; 165 cin>>ins; 166 changeaddr(p, ins);break; 167 case 2: system("CLS"); a=wang();break; 168 default:cout<<"輸入有誤,請重新輸入!"<<endl;break; 169 } 170 } 171 } 172 173 void menu() 174 { 175 int a; 176 printf("\t\t\t--------------------------------\n"); 177 printf("\t\t\t☆☆歡迎使用分頁模擬實驗系統☆☆\n"); 178 printf("\t\t\t---------------------------------\n"); 179 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 180 printf("\t\t\t☆☆1.輸入指令 ☆☆\n"); 181 printf("\t\t\t☆☆------------------------☆☆\n"); 182 printf("\t\t\t☆☆2.進入頁面置換演算法 ☆☆\n"); 183 printf("\t\t\t☆☆------------------------☆☆\n"); 184 printf("\t\t\t☆☆0.EXIT ☆☆\n"); 185 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 186 printf("請選擇所要執行的操作:"); 187 scanf("%d",&a); 188 switch(a) 189 { 190 case 0: printf("\t\t\t-再見!-\t\t\t\n");break; 191 case 1: dizhizhuanhuan (); break; 192 case 2: wang (); break; 193 default:cout<<"輸入有誤,請重新輸入!"<<endl;break; 194 } 195 } 196 int main() 197 { 198 menu(); 199 } 200 201 //****************隨機產生序列號函式 202 int* build() 203 { 204 printf("隨機產生一個行程式列號為:\n"); 205 int i=0; 206 for(i=0; i<psize; i++) 207 { 208 pro[i]=10*rand()/(RAND_MAX+1)+1; 209 printf("%d ", pro[i]); 210 } 211 printf("\n"); 212 return(pro); 213 } 214 215 //***************************************查找空閑物理塊 216 int searchpb() 217 { 218 for (j=0;j<bsize; j++) 219 { 220 if(phb[j] == 0) 221 { 222 m=j; 223 return m; 224 break; 225 } 226 } 227 return -1; 228 } 229 //************************************查找相同行程 230 int searchpro() 231 { 232 for(j=0;j< bsize;j++) 233 { 234 if(phb[j] =pro[i]) 235 { 236 n=j; 237 return j; 238 } 239 } 240 return -1; 241 } 242 243 //*************************初始化記憶體 244 void empty() 245 { 246 for(i=0;i<bsize;i++) 247 phb[i]=0; 248 count=0; //計數器置零 249 } //******先進先出頁面置換演算法 250 void FIFO() 251 { 252 for( i=0; i<psize; i++) 253 { 254 // m=searchpb(); 255 // n=searchpro(); 256 //找到第一個空閑的物理快 257 for(j=0;j<bsize;j++) { 258 if(phb[j] == 0){ 259 m=j; 260 break; 261 } 262 } 263 //找與行程相同的標號 264 for(j=0;j<bsize;j++) { 265 if(phb[j] == pro[i]){ 266 n=j; 267 } 268 } 269 270 //找flag值最大的 271 for(j=0;j<bsize;j++) 272 { 273 if(flag[j]>maxflag) 274 { 275 maxflag = flag[j]; 276 mmax = j; 277 } 278 } 279 280 if(n == -1)//不存在相同行程 281 { 282 if(m != -1)//存在空閑物理塊 283 { 284 phb[m]=pro[i];//行程號填入該空閑物理塊 285 // count++; 286 flag[m]=0; 287 for (j=0;j<=m; j++) 288 { 289 flag[j]++; 290 } 291 m=-1; 292 } 293 else//不存在空閑物理塊 294 { 295 phb[mmax] =pro[i]; 296 flag[mmax] =0; 297 for (j=0;j<bsize;j++) 298 { 299 flag[j]++; 300 } 301 mmax = -1; 302 maxflag = 0; 303 count++; 304 } 305 } 306 else//存在相同的行程 307 { 308 phb[n] = pro[i]; 309 for(j=0;j<bsize;j++) 310 { 311 flag[j]++; 312 } 313 n=-1; 314 } 315 for(j=0;j < bsize;j++) 316 { 317 printf("%d ", phb[j]); 318 } 319 printf("\n"); 320 } 321 printf("缺頁次數為:%d\n",count); 322 printf("缺頁率 :%16. 6f",(float)count/psize); 323 printf("\n"); 324 } 325 /*初始化記憶體單元、緩沖區*/ 326 void Init(Pagel *b,int c[bsize][psize]) 327 { 328 int i,j; 329 for (i=0;i<psize;i++) 330 { 331 b[i].num=-1; 332 b[i].time=psize-i-1; 333 } 334 for(i=0;i<bsize;i++) 335 for(j=0;j<psize;j++) 336 c[i][j]=-1; 337 } 338 /*取得在記憶體中停留最久的頁面,默認狀態下為最早調入的頁面*/ 339 int GetMax(Pagel *b) 340 { 341 int i; 342 int max=-1; 343 int tag=0; 344 for(i=0;i<bsize;i++) 345 { 346 if(b[i].time>max) 347 { 348 max=b[i].time; 349 tag= i; 350 } 351 } 352 return tag; 353 } 354 355 /*判斷頁面是否已在記憶體中*/ 356 int Equation(int fold, Pagel *b) 357 { 358 int i; 359 for(i=0;i<bsize;i++) 360 { 361 if(fold==b[i]. num) 362 return i; 363 } 364 return -1; 365 } 366 /*LRU核心部分*/ 367 void Lruu(int fold, Pagel *b) 368 { 369 int i; 370 int val; 371 val=Equation(fold, b); 372 if (val>=0) 373 { 374 b[val].time=0; 375 for(i=0;i<bsize;i++) 376 if (i!=val) 377 b[i].time++; 378 } 379 else 380 { 381 queue[++k]=fold;/*記錄調入頁面*/ 382 val=GetMax(b); 383 b[val].num=fold; 384 b[val].time=0; 385 for (i=0;i<bsize;i++){ 386 387 // URLcount++; 388 if (i!=val) 389 b[i].time++; 390 } 391 } 392 } 393 394 void LRU() 395 { 396 int i,j; 397 k=0; 398 Init(b, c); 399 for(i=0; i<psize; i++) 400 { 401 Lruu(pro[i],b); 402 c[0][i]=pro[i]; 403 /*記錄當前的記憶體單元中的頁面*/ 404 for(j=0;j<bsize;j++) 405 c[j][i]=b[j].num; 406 } 407 408 /*結果輸出*/ 409 printf("記憶體狀態為:\n"); 410 Myprintf; 411 for(j=0;j<psize;j++) 412 printf("|%2d", pro[j]); 413 printf("|\n"); 414 Myprintf; 415 416 for(i=0;i<bsize;i++) 417 { 418 for(j=0; j<psize; j++) 419 { 420 if(c[i][j]==-1) 421 printf("|%2c",32); 422 else 423 printf("|%2d",c[i][j]); 424 } 425 printf("|\n"); 426 } 427 428 Myprintf; 429 // printf("\n調入佇列為:"); 430 // for(i=0;i<k;i++) 431 // printf("%3d", queue[i]); 432 433 printf("\n缺頁次數為:%6d\n 缺頁率 :%16. 6f", k+1,(float)(k+1)/psize); 434 } 435 436 //********主函式 437 int wang() 438 { 439 int sel; 440 do{ 441 printf("\t\t\t--------------------------------\n"); 442 printf("\t\t\t☆☆歡迎使用分頁模擬實驗系統☆☆\n"); 443 printf("\t\t\t---------------------------------\n"); 444 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 445 printf("\t\t\t☆☆ 虛擬記憶體 ☆☆\n"); 446 printf("\t\t\t☆☆------------------------☆☆\n"); 447 printf("\t\t\t☆☆1.產生隨機序列 ☆☆\n"); 448 printf("\t\t\t☆☆------------------------☆☆\n"); 449 printf("\t\t\t☆☆2.最近最久未使用 ☆☆\n"); 450 printf("\t\t\t☆☆------------------------☆☆\n"); 451 printf("\t\t\t☆☆3.先進先出 ☆☆\n"); 452 printf("\t\t\t☆☆------------------------☆☆\n"); 453 printf("\t\t\t☆☆0.退出 ☆☆\n"); 454 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 455 printf("請選擇所要執行的操作:"); 456 scanf("%d",&sel); 457 switch(sel) 458 { 459 case 0: printf("\t\t\t再見!t\t\t\n"); break; 460 case 1: build(); break; 461 case 2: printf("最近最久未使用\n"); LRU();empty(); printf("\n");break; 462 case 3: printf("先進先出演算法\n"); FIFO();empty();printf("\n");break; 463 default:printf("請輸入正確的選項號!");printf("\n\n");break; 464 } 465 }while(sel !=0 ); 466 return sel; 467 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/379375.html
標籤:其他
上一篇:Apache Log4j 爆核彈級漏洞,Spring Boot 默認日志框架就能完美躲過!!
下一篇:Python——連接資料庫操作
