1. 程式人生 > >操作系統,時間片輪轉算法的C語言實現Round Robin

操作系統,時間片輪轉算法的C語言實現Round Robin

cst 輪轉 初始 finish ont 建立 c語言 %d stat

  1 #include "windows.h"
  2 #include <conio.h>
  3 #include <stdlib.h>
  4 #include <fstream.h>
  5 #include <io.h>
  6 #include <string.h>
  7 #include <stdio.h>
  8 
  9 void Create_ProcInfo(); // 建立進程調度需要的數據
 10 void Display_ProcInfo();   // 顯示當前系統全部進程的狀態
 11 void
Scheduler_FF(); 12 void Cpu_Sched(); 13 void IO_Sched(); 14 void NextRunProcess(); 15 void DisData(); 16 void DisResult(); 17 18 int RunPoint; // 運行進程指針,-1時為沒有運行進程 19 int WaitPoint; // 阻塞隊列指針,-1時為沒有阻塞進程 20 int ReadyPoint; // 就緒隊列指針,-1時為沒有就緒進程 21 long ClockNumber; // 系統時鐘 22 int ProcNumber; //
系統中模擬產生的進程總數 23 int FinishedProc; // 系統中模擬產生的進程總數 24 int q=9;//時間片 25 26 27 //進程信息結構 28 struct ProcStruct 29 { 30 int p_pid; // 進程的標識號 31 char p_state; // 進程的狀態,C--運行 R--就緒 W--組塞 B--後備 F--完成 32 int p_rserial[16]; // 模擬的進程執行的CPU和I/O時間數據序列,間隔存儲,0項存儲有效項數 33 int
p_pos; // 當前進程運行到的序列位置 34 int p_starttime; // 進程建立時間 35 int p_endtime; // 進程運行結束時間 36 int p_cputime; // 當前運行時間段進程剩余的需要運行時間 37 int p_iotime; // 當前I/O時間段進程剩余的I/O時間 38 int p_next; // 進程控制塊的鏈接指針 39 int p_excutetime; // 記錄一次時間片內執行的時間 40 } proc[10]; 41 42 //////////////////////////////////////////////////////////////////////////// 43 // 44 // 隨機生成進程數量和每個CPU--I/O時間數據序列,進程數量控制在5到10之間, // 45 // 數據序列控制在6到12之間,CPU和I/O的時間數據值在5到15的範圍 // 46 // 47 //////////////////////////////////////////////////////////////////////////// 48 49 void Create_ProcInfo(void ) 50 { 51 int s,i,j; 52 53 srand(GetTickCount()); // 初始化隨機數隊列的"種子" 54 ProcNumber=((float) rand() / 32767) * 5 ; // 隨機產生進程數量5~10 55 56 57 for(i=0;i<ProcNumber;i++) // 生成進程的CPU--I/O時間數據序列 58 { 59 proc[i].p_pid=((float) rand() / 32767) * 1000; 60 proc[i].p_state=B; // 初始都為後備狀態 61 62 s=((float) rand() / 32767) *6 + 2; // 產生的進程數據序列長度在6~12間 63 proc[i].p_rserial[0]=s; // 第一項用於記錄序列的長度 64 for(j=1;j<=s;j++) // 生成時間數據序列 65 proc[i].p_rserial[j]=((float) rand() / 32767) *10 + 5; 66 // 賦其他字段的值 67 proc[i].p_pos=1; 68 proc[i].p_starttime=((float) rand() / 32767) *49+1; // 隨機設定進程建立時間 69 proc[i].p_endtime=0; 70 proc[i].p_cputime=proc[i].p_rserial[1]; 71 proc[i].p_iotime=proc[i].p_rserial[2]; 72 proc[i].p_next=-1; 73 proc[i].p_excutetime=0; 74 } 75 printf("\n---------------------------\n 建立了%2d 個進程數據序列\n\n", ProcNumber); 76 DisData(); 77 printf("\nPress Any Key To Continue......."); 78 _getch() ; 79 return ; 80 } 81 82 //////////////////////////////////////////////////////////////////////// 83 84 // 顯示系統當前狀態 85 86 //////////////////////////////////////////////////////////////////////// 87 88 void Display_ProcInfo(void) 89 { int i,n; 90 91 system("cls") ; 92 printf("時間片為%d",q); 93 printf("\n 當前系統模擬%2d 個進程的運行 時鐘:%ld\n\n", ProcNumber,ClockNumber); 94 95 printf(" 就緒指針=%d, 運行指針=%d, 阻塞指針=%d\n\n",ReadyPoint,RunPoint,WaitPoint ); 96 if(RunPoint!= -1) 97 { 98 printf(" 當前運行的進程 No.%d ID:%d\n", RunPoint,proc[RunPoint].p_pid); 99 printf(" %6d,%6d,%6d\n",proc[RunPoint].p_starttime,proc[RunPoint].p_rserial[proc[RunPoint].p_pos],proc[RunPoint].p_cputime); 100 printf("當前運行的進程執行的時間為%d",proc[RunPoint].p_excutetime); 101 printf("當前運行的進程執行的cpu時間為%d",proc[RunPoint].p_cputime); 102 } 103 else 104 printf(" 當前運行的進程ID:No Process Running !\n"); 105 106 n=ReadyPoint; 107 printf("\n Ready Process ...... \n"); 108 while(n!=-1) // 顯示就緒進程信息 109 { 110 printf(" No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_cputime ); 111 n=proc[n].p_next; 112 } 113 114 n=WaitPoint; 115 printf("\n Waiting Process ...... \n"); 116 while(n!=-1) // 顯示阻塞進程信息 117 { 118 printf(" No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_iotime); 119 n=proc[n].p_next; 120 } 121 122 printf("\n=================== 後備進程 ====================\n"); 123 for(i=0; i<ProcNumber; i++) 124 if (proc[i].p_state==B) 125 printf(" No.%d ID:%5d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime); 126 127 printf("\n================ 已經完成的進程 =================\n"); 128 for(i=0; i<ProcNumber; i++) 129 if (proc[i].p_state==F) 130 printf("No.%d ID:%5d,%6d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime,proc[i].p_endtime); 131 132 } 133 134 //////////////////////////////////////////////////////////////////////// 135 136 // 顯示模擬執行的結果 137 138 //////////////////////////////////////////////////////////////////////// 139 void DisResult(void) 140 { int i; 141 printf("\n---------------------------------\n"); 142 for(i=0; i<ProcNumber; i++) 143 { 144 printf("ID=%4d> %2d ",proc[i].p_pid ,proc[i].p_rserial[0] ); 145 printf("%4d,%4d",proc[i].p_starttime,proc[i].p_endtime); 146 printf("\n" ); 147 } 148 } 149 150 //////////////////////////////////////////////////////////////////////// 151 152 // 顯示進程數據序列 153 154 //////////////////////////////////////////////////////////////////////// 155 void DisData(void) 156 { int i,j; 157 158 for(i=0; i<ProcNumber; i++) 159 { 160 printf("ID=%4d %2d > ",proc[i].p_pid ,proc[i].p_rserial[0] ); 161 for(j=1; j<=proc[i].p_rserial[0];j++) 162 printf("%4d",proc[i].p_rserial[j]); 163 printf("\n" ); 164 } 165 } 166 //////////////////////////////////////////////////////////////////////// 167 168 // 選擇下一個可以運行的進程 169 170 //////////////////////////////////////////////////////////////////////// 171 void NextRunProcess(void) 172 { 173 if (ReadyPoint==-1) { RunPoint = -1; return;} // 就緒隊列也沒有等待的進程 174 175 proc[ReadyPoint].p_state =C; //ReadyPoint所指示的進程狀態變為執行狀態 176 RunPoint=ReadyPoint; 177 if( proc[ReadyPoint].p_excutetime==-1)//進程為執行成功,接著上次的cpu時間執行 178 { 179 proc[ReadyPoint].p_excutetime=0; 180 } 181 else 182 proc[ReadyPoint].p_cputime =proc[ReadyPoint].p_rserial[proc[ReadyPoint].p_pos] ; 183 ReadyPoint=proc[ReadyPoint].p_next; 184 proc[RunPoint].p_next = -1; 185 186 } 187 //////////////////////////////////////////////////////////////////////// 188 189 // CPU調度 190 191 //////////////////////////////////////////////////////////////////////// 192 193 void Cpu_Sched(void) 194 { 195 int n; 196 197 if (RunPoint == -1) // 沒有進程在CPU上執行 198 { NextRunProcess(); return; } 199 200 proc[RunPoint].p_cputime--; // 進程CPU執行時間減少1個時鐘單位 201 proc[RunPoint].p_excutetime++; 202 if((proc[RunPoint].p_cputime == 0&&proc[RunPoint].p_excutetime<=q))//若時間片未完,但進程已經結束 203 { 204 //printf("若時間片未完,但進程已經結束\n"); 205 proc[RunPoint].p_excutetime=0;//清空運行時間 206 // 進程完成本次CPU後的處理 207 if (proc[RunPoint].p_rserial[0]==proc[RunPoint].p_pos) //進程全部序列執行完成 208 { 209 FinishedProc++; 210 proc[RunPoint].p_state =F; 211 proc[RunPoint].p_endtime = ClockNumber; 212 RunPoint=-1; //無進程執行 213 NextRunProcess(); 214 } 215 else //進行IO操作,進入阻塞隊列 216 { 217 proc[RunPoint].p_pos++; 218 proc[RunPoint].p_state =W; 219 proc[RunPoint].p_iotime =proc[RunPoint].p_rserial[proc[RunPoint].p_pos]; 220 printf("進入阻塞隊列\n"); 221 n=WaitPoint; 222 if(n == -1) //是阻塞隊列第一個I/O進程 223 WaitPoint=RunPoint; 224 else 225 { do //放入阻塞隊列第尾 226 { 227 if(proc[n].p_next == -1) 228 { proc[n].p_next = RunPoint; 229 break; 230 } 231 n=proc[n].p_next; 232 } while(n!=-1) ; 233 } 234 RunPoint=-1; 235 NextRunProcess(); 236 } 237 return; 238 } 239 if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime<q)//時間片未完 程序未執行結束 繼續執行 240 { 241 //printf("時間片未完 程序未執行結束 繼續執行\n"); 242 return; 243 } 244 //{ printf("\n RunPoint=%d,ctime=%d",RunPoint,proc[RunPoint].p_cputime);getchar();return; } 245 if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime==q)//時間片完,但是程序未執行完 放到就緒隊列尾部 246 { 247 //printf("時間片完,但是程序未執行完 放到就緒隊列尾部\n"); 248 int n; 249 proc[RunPoint].p_state=R; // 進程狀態修改為就緒 250 proc[RunPoint].p_next=-1; 251 proc[RunPoint].p_excutetime=-1;//清空運行時間,-1代表程序未執行完成 252 if(ReadyPoint==-1) // 就緒隊列無進程 253 ReadyPoint=RunPoint; 254 else // 就緒隊列有進程,放入隊列尾 255 { 256 n=ReadyPoint; 257 while(proc[n].p_next!=-1) n=proc[n].p_next; 258 proc[n].p_next=RunPoint; 259 } 260 RunPoint=-1; 261 NextRunProcess(); //執行下一個進程 262 } 263 264 } 265 266 267 268 //////////////////////////////////////////////////////////////////////// 269 270 // I/O調度 271 272 //////////////////////////////////////////////////////////////////////// 273 274 void IO_Sched(void) 275 { 276 int n,bk; 277 278 if (WaitPoint==-1) return; // 沒有等待I/O的進程,直接返回 279 280 proc[WaitPoint].p_iotime--; // 進行1個時鐘的I/O時間 281 282 if (proc[WaitPoint].p_iotime > 0) return; // 還沒有完成本次I/O 283 284 // 進程的I/O完成處理 285 if (proc[WaitPoint].p_rserial[0]==proc[WaitPoint].p_pos) //進程全部任務執行完成 286 { 287 FinishedProc++; 288 proc[WaitPoint].p_endtime = ClockNumber; 289 proc[WaitPoint].p_state =F; 290 291 if(proc[WaitPoint].p_next==-1) 292 { WaitPoint=-1;return ;} 293 else //調度下一個進程進行I/O操作 294 { 295 n=proc[WaitPoint].p_next; 296 proc[WaitPoint].p_next=-1; 297 WaitPoint=n; 298 proc[WaitPoint].p_iotime =proc[WaitPoint].p_rserial[proc[WaitPoint].p_pos] ; 299 return ; 300 } 301 } 302 else //進行下次CPU操作,進就緒隊列 303 { 304 bk=WaitPoint; 305 WaitPoint=proc[WaitPoint].p_next; 306 307 proc[bk].p_pos++; 308 proc[bk].p_state =R; //進程狀態為就緒 309 proc[bk].p_cputime = proc[bk].p_rserial[proc[bk].p_pos]; 310 proc[bk].p_next =-1; 311 312 n=ReadyPoint; 313 if(n == -1) //是就緒隊列的第一個進程 314 { ReadyPoint=bk; return; } 315 else 316 { do 317 { 318 if(proc[n].p_next == -1) { proc[n].p_next = bk; break ; } 319 n=proc[n].p_next; 320 } 321 while(n!=-1); 322 } 323 } 324 return ; 325 } 326 327 328 329 330 331 //////////////////////////////////////////////////////////////////////// 332 333 // 檢查是否有新進程到達,有則放入就緒隊列 334 335 //////////////////////////////////////////////////////////////////////// 336 337 void NewReadyProc(void) 338 { 339 int i,n; 340 341 for(i=0; i<ProcNumber; i++) 342 { 343 if (proc[i].p_starttime == ClockNumber) // 進程進入時間達到系統時間 344 { 345 proc[i].p_state=R; // 進程狀態修改為就緒 346 proc[i].p_next=-1; 347 348 if(ReadyPoint==-1) // 就緒隊列無進程 349 ReadyPoint=i; 350 else // 就緒隊列有進程,放入隊列尾 351 { 352 n=ReadyPoint; 353 while(proc[n].p_next!=-1) n=proc[n].p_next; 354 proc[n].p_next=i; 355 } 356 } 357 } // for 358 return; 359 } 360 361 362 //////////////////////////////////////////////////////////////////////// 363 364 // 調度模擬算法 365 366 //////////////////////////////////////////////////////////////////////// 367 368 void Scheduler_FF(void) 369 { 370 FinishedProc=0; 371 if(ProcNumber==0) 372 { printf(" 必須首先建立進程調度數據 ! \n"); 373 system("cls"); return; 374 } 375 376 ClockNumber=0;// 時鐘開始計時, 開始調度模擬 377 while(FinishedProc < ProcNumber) // 執行算法 378 { 379 ClockNumber++; // 時鐘前進1個單位 380 NewReadyProc(); // 判別新進程是否到達 381 Cpu_Sched(); // CPU調度 382 IO_Sched(); // IO調度 383 Display_ProcInfo(); //顯示當前狀態 384 } 385 DisResult(); 386 getch(); return; 387 } 388 389 void Change_q(void) 390 { 391 scanf("%d",&q); 392 } 393 394 /////////////////////////////////////////////////////////////////// 395 396 // 主函數 397 398 /////////////////////////////////////////////////////////////////// 399 400 int main(int argc, char* argv[]) 401 { 402 char ch; 403 404 RunPoint=-1; // 運行進程指針,-1時為沒有運行進程 405 WaitPoint=-1; // 阻塞隊列指針,-1時為沒有阻塞進程 406 ReadyPoint=-1; // 就緒隊列指針,-1時為沒有就緒進程 407 ClockNumber=0; // 系統時鐘 408 ProcNumber=0; // 當前系統中的進程總數 409 410 system("cls") ; 411 while ( true ) 412 { 413 printf("***********************************\n"); 414 printf(" 1: 建立進程調度數據序列 \n") ; 415 printf(" 2: 執行調度算法\n") ; 416 printf(" 3: 顯示調度結果 \n") ; 417 printf(" 4: 更改時間片 \n"); 418 printf(" 5: 退出\n") ; 419 printf("***********************************\n"); 420 printf( "Enter your choice (1 ~ 5): "); 421 422 do{ //如果輸入信息不正確,繼續輸入 423 ch = (char)_getch() ; 424 } while(ch != 1 && ch != 2&& ch != 3&& ch != 4&& ch != 5); 425 426 if(ch == 5) { printf( "\n");return 0; } // 選擇4,退出 427 if(ch == 3) DisResult(); // 選擇3 428 if(ch == 2) Scheduler_FF(); // 選擇2 429 if(ch == 1) Create_ProcInfo(); // 選擇1 430 if(ch == 4) Change_q(); 431 _getch() ; 432 system("cls") ; 433 } 434 //結束 435 printf("\nPress Any Key To Continue:"); 436 _getch() ; 437 return 0; 438 }

操作系統,時間片輪轉算法的C語言實現Round Robin