系統把處理機分配給優先權最高的進程,使之執行。但在其執行期間,只要又出現了另一個其優先權更高的進程,進程調度程序就立即停止當前進程(原優先權最高的進程)的執行,重新將處理機分配給新到的優先權最高的進程。
本教程操作環境:windows7系統、C++17版本、Dell G3電腦。
搶占式優先權調度算法
在這種方式下,系統把處理機分配給優先權最高的進程,使之執行。但在其執行期間,只要又出現了另一個其優先權更高的進程,進程調度程序就立即停止當前進程(原優先權最高的進程)的執行,重新將處理機分配給新到的優先權最高的進程。因此,在采用這種調度算法時,是每當系統中出現一個新的就緒進程i 時,就將其優先權Pi與正在執行的進程j 的優先權Pj進行比較。如果Pi≤Pj,原進程Pj便繼續執行;但如果是Pi>Pj,則立即停止Pj的執行,做進程切換,使i 進程投入執行。顯然,這種搶占式的優先權調度算法能更好地滿足緊迫作業的要求,故而常用於要求比較嚴格的實時系統中,以及對性能要求較高的批處理和分時系統中。
具體代碼:

1 #include #include #include using namespace std;using std::cout;struct PCB 2 3 { // 進程名 4 5 string name; // 到達時間 6 7 int arrivetime; // 運行時間 8 9 int runtime; 10 11 // 仍需運行時間 12 13 int resttime; // 開始時間 14 15 int starttime; // 完成時間 16 17 int endtime; // 運行次數 18 19 int runcount; // 周轉時間 20 21 int zhouzhuangtime; // 帶權周轉時間(周轉時間/運行時間) 22 23 double weightzhouzhuangtime; // 優先級(靜態) 24 25 int priority; 26 27 28 29 PCB *next; 30 31 };// 進程數int num_process;// 記錄所有進程的總時間int totaltime;// 記錄所有進程的總帶權周轉時間double weighttotaltime; 32 33 34 35 PCB *createPCB() 36 37 { int i; // 定義隊首、隊尾 38 39 PCB *head, *rear; // 初始化 40 41 head = rear = NULL; // 臨時指針變量 42 43 PCB *p; cout<<"請輸入進程數量:"; cin>>num_process; for(i = 0; i < num_process; i++) 44 45 { // 初始化一個空間給進程 46 47 p = new PCB; cout<<"請依次輸入第"<>p->name>>p->priority>>p->arrivetime>>p->runtime; 48 49 p->resttime = p->runtime; 50 51 p->runcount = 1; 52 53 totaltime += p->runtime; 54 55 p->starttime = 0; 56 57 p->endtime = 0; 58 59 p->zhouzhuangtime = 0; 60 61 p->weightzhouzhuangtime = 0; 62 63 p->next = NULL; // 存入鏈表中 64 65 if(rear == NULL) 66 67 { 68 69 head = p; 70 71 rear = p; 72 73 } else 74 75 { 76 77 rear->next = p; 78 79 rear = p; 80 81 } 82 83 84 85 } return head; 86 87 }// 鏈表插入排序PCB *insertSort(PCB *head) 88 89 { /* 90 91 1、先在原鏈表中以第一個節點為一個有序鏈表,其余節點為待定節點; 92 93 2、從待定節點中取節點,插入到有序鏈表中相應位置; 94 95 3、實際上只有一條鏈表,在排序中,實際只增加了一個用於指向剩下需要排序節點的頭指針。 96 97 */ 98 99 PCB *first;// 為原鏈表剩下用於直接插入排序的節點頭指針 100 101 PCB *t; // 臨時指針變量:要插入的節點 102 103 PCB *p; // 臨時指針變量:要插入的位置 104 105 PCB *q; // 臨時指針變量:指向原鏈表 106 107 108 109 first = head->next; 110 111 head->next = NULL; // 只含有一個節點的鏈表的有序鏈表 112 113 114 115 while(first != NULL) // 遍歷剩下的無序鏈表 116 117 { // 無序節點在有序鏈表中找插入位置p 118 119 for(t = first, q = head; (q != NULL) && (q->arrivetime < t->arrivetime); p = q, q = q->next); // 無序鏈表中的節點離開,以便插入到有序鏈表中 120 121 first = first->next; if(q == head)// 插入在第一個節點之前 122 123 { 124 125 head = t; 126 127 } else// p是q的前驅 128 129 { 130 131 p->next = t; 132 133 } 134 135 t->next = q;// 完成插入動作 136 137 } return head; 138 139 }// 獲取當前時間段內的進程數量int getCurrentNumOfProcess(PCB *head, int time) 140 141 { int count = 0; 142 143 PCB *t;// 臨時指針變量,指向鏈表 144 145 t = head; while(t != NULL && t->arrivetime <= time) 146 147 { 148 149 count++; 150 151 t = t->next; 152 153 } return count; 154 155 }// 刪除當前節點PCB* deletePCB(PCB *head, PCB *t) 156 157 { 158 159 PCB *p, *q; 160 161 p = head; 162 163 q = p->next; // 刪除節點是頭節點 164 165 if(t == head) 166 167 { 168 169 head = head->next; 170 171 } else 172 173 { while(q != t)// 跳出循環之后q為該節點,p為前一節點 174 175 { 176 177 p = p->next; 178 179 q = p->next; 180 181 } if(t->next == NULL)// 刪除節點是尾節點 182 183 p->next = NULL; else 184 185 p->next = q->next; 186 187 } // 刪除 188 189 free(t); return head; 190 191 }// 在頭節點后的count個節點中選擇優先數最大的返回PCB *findMaxPriority(PCB *head, int count) 192 193 { int max; 194 195 PCB *p, *q, *f; 196 197 q = head; 198 199 max = q->priority; 200 201 f = q; while(count > 0) 202 203 { if(q->priority > max) 204 205 { 206 207 max = q->priority; 208 209 f = q; 210 211 } 212 213 count--; 214 215 q =q->next; 216 217 } return f; 218 219 220 221 }/* 222 223 輸出a時間內的特定輸出格式,當某一時間段內沒有進程工作時,進程名稱為0 224 225 進程名稱.進程工作時間,進程與進程間以|分隔 226 227 輸入:1 3 2 8 228 229 2 2 1 7 230 231 3 6 3 12 232 233 輸出:[0.1|2.1|1.1|3.12|1.7|2.6|0.172] 234 235 */void print(vector vec_output, int a) 236 237 { for(int i = 0; i < vec_output.size(); i++) 238 239 { cout<<"******************************************"< 240 } // 輸出周轉時間信息,只有進程結束了才輸出 241 242 int i; for(i = 0; i < vec_output.size()-1; i++) 243 244 { bool flag = true; for(int j = i+1; j < vec_output.size(); j++) 245 246 { if(vec_output[j].name == vec_output[i].name) 247 248 { 249 250 flag = false; break; 251 252 } 253 254 } if(flag) 255 256 { cout<<"進程"< 257 } 258 259 } cout<<"進程"< 260 cout<<"平均周轉時間:"< 0) 261 262 { cout<<"0."< 263 } if(vec_output[vec_output.size() - 1].endtime < a) 264 265 { for(int i = 0; i < vec_output.size(); i++) 266 267 { cout< 268 if(i+1 < vec_output.size() && vec_output[i].endtime != vec_output[i+1].starttime) 269 270 { cout<<"0."< 271 } 272 273 } cout<<"0."< 274 } else if(vec_output[vec_output.size() - 1].endtime == a) 275 276 { for(int i = 0; i < vec_output.size()-1; i++) 277 278 { cout< 279 if(i+1 < vec_output.size() && vec_output[i].endtime != vec_output[i+1].starttime) 280 281 { cout<<"0."< 282 } 283 284 } cout< 285 } else 286 287 { for(int i = 0; i < vec_output.size(); i++) 288 289 { if(vec_output[i].endtime <= a) 290 291 { cout< 292 if(i+1 < vec_output.size() && vec_output[i].endtime != vec_output[i+1].starttime) 293 294 { cout<<"0."< 295 } 296 297 } else 298 299 { cout< 300 } 301 302 } 303 304 } 305 306 }void PCB_MAIN(PCB *head) 307 308 { 309 310 head = insertSort(head); int time = 0;// 模擬時間變量 311 312 int count;// 當前時間內運行的進程數量 313 314 PCB *q; vector vec_out;//輸出 315 316 PCB temp; while(head != NULL) 317 318 { 319 320 count = getCurrentNumOfProcess(head, time); if(count == 0) 321 322 time++; else 323 324 { /************************************************************************/ 325 326 /* 搶占式 */ 327 328 /************************************************************************/ 329 330 // 找出優先數最大的線程 331 332 q = findMaxPriority(head, count); if(q->runcount == 1)// 該進程第一次運行 333 334 { 335 336 q->starttime = time; // 輸出信息 337 338 temp = *q; 339 340 temp.endtime = 0; 341 342 temp.next = NULL; if(vec_out.size() != 0 && vec_out[vec_out.size()-1].endtime == 0) 343 344 { 345 346 vec_out[vec_out.size()-1].endtime = temp.starttime; 347 348 } 349 350 vec_out.push_back(temp); 351 352 } 353 354 ++time; 355 356 ++q->runcount; 357 358 --q->resttime; if(q->resttime == 0)// 該進程運行結束 359 360 { // 記錄結束時間 361 362 q->endtime = time; // 計算周轉時間 363 364 q->zhouzhuangtime = time - q->arrivetime; // 計算帶權周轉時間 365 366 q->weightzhouzhuangtime = q->zhouzhuangtime/(double)q->runtime; 367 368 weighttotaltime += q->weightzhouzhuangtime; // 輸出信息 369 370 temp = *q; 371 372 temp.starttime = 0; 373 374 temp.next = NULL; if(vec_out[vec_out.size()-1].name == temp.name) 375 376 { 377 378 vec_out[vec_out.size()-1].endtime = temp.endtime; 379 380 vec_out[vec_out.size()-1].zhouzhuangtime = temp.zhouzhuangtime; 381 382 vec_out[vec_out.size()-1].weightzhouzhuangtime = temp.weightzhouzhuangtime; 383 384 } else 385 386 { 387 388 temp.starttime = vec_out[vec_out.size()-1].endtime; 389 390 vec_out.push_back(temp); 391 392 } // 刪除該進程 393 394 //deletePCB(q); 395 396 head = deletePCB(head, q); 397 398 } 399 400 } 401 402 } // 輸出200時間單位內的執行順序 403 404 print(vec_out, 200); 405 406 }int main() 407 408 { 409 410 PCB *head = NULL; 411 412 head = createPCB(); 413 414 PCB_MAIN(head); return 0; 415 416 }
輸出實例
輸入:
輸出:
以上就是搶占式優先級調度算法是什么意思的詳細內容。(拼多多培訓)