1、什么是進程調度
無論是在批處理系統還是分時系統中,用戶進程數一般都多於處理機數、這將導致它們互相爭奪處理機。另外,系統進程也同樣需要使用處理機。這就要求進程調度程序按一定的策略,動態地把處理機分配給處於就緒隊列中的某一個進程,以使之執行。
2、處理機調度分類
- 高級調度:(High-Level Scheduling)又稱為作業調度,它決定把后備進程調入內存運行;
- 低級調度:(Low-Level Scheduling)又稱為進程調度,它決定把就緒隊列的某進程獲得CPU;
- 中級調度:(Intermediate-Level Scheduling)又稱為在虛擬存儲器中引入,在內、外存對換區進行進程對換。
3、短進程優先
#include "stdio.h" #include <stdlib.h> #include "string.h" #define NULL 0 typedef struct pcb { char name[10]; //進程名稱 int ArrivalTime; //到達時間 int StartTime; //開始運行時間 int FinishTime; //結束運行時間 int WholeTime; //運行所需時間 struct pcb *link; //下一個指針 }pcb; int N; //運行的進程數量 void input(); pcb *ready=NULL,*p=NULL,*finish = NULL; //ready 是初始時的狀態,finish 是結束時狀態 int M;
void input() { printf("請輸入進程數量:"); scanf("%d",&N); //N為全局變量 M = N; struct pcb *q = ready; int i = 0; for( i=0 ;i<N;i++) { printf("請輸入第 %d 個進程信息-----------\n",i+1); p = (pcb *)malloc(sizeof(pcb)); printf("請輸入進程名:") ; scanf("%s",p->name); printf("請輸入進程到達時間:"); scanf("%d",&p->ArrivalTime); printf("請輸入進程運行時間:"); scanf("%d",&p->WholeTime); p->link = NULL; if(NULL == ready) { ready = p; q = ready; } else { q = ready; while(NULL != q->link) //將q移動到就緒隊列最后一個進程 { q = q->link; } p->link = NULL; q->link = p; q=p; } printf("\n"); } q= NULL; free(q); }
//先輸入的肯定是先到達的 //nowTime 是現在執行的時間 pcb* sjf(int nowTime,int *after) { int i = 0 ; pcb *nowProgress=NULL, *p = ready; int ProgressNum = 0; // 當前最短的是第幾個線程 int minTime =0; // 最短運行時間 if(NULL != ready) { while(NULL != p) //遍歷整個鏈表,查找出最短的進程,即運行時間最短 { // printf("\n%d %d %d \n",p->ArrivalTime,nowTime >= p->ArrivalTime,nowTime) ; if(nowTime >= p->ArrivalTime) { if(0 == minTime) //首次賦值 { nowProgress = p; minTime = p->WholeTime; } else { if(p->WholeTime < minTime) { nowProgress = p; minTime = p->WholeTime; } } *after = minTime+nowTime; } p = p->link; } } return nowProgress; }
void output(pcb *p,int now_time) { if(NULL == p) { printf("當前時刻:%d,暫無進程在運行!\n",now_time); } else { printf("進程名:%s,運行時間:%d,到達時間:%d\n",p->name,p->WholeTime,p->ArrivalTime); } }
5》、輸出進程運行總體情況統計
void outputAll() { pcb *p = finish; printf("\n-----------------------統計結果:-------------------\n"); float avgRevolve = 0; float avgSuperRevolve = 0; while(NULL != p) { avgRevolve += p->StartTime+p->WholeTime-p->ArrivalTime; avgSuperRevolve += 1.0*(p->StartTime+p->WholeTime-p->ArrivalTime)/p->WholeTime; printf("\n進程名:%s,開始時間%d,結束時間:%d,運行時間:%d,到達時間:%d\n",p->name,p->StartTime,p->FinishTime,p->WholeTime,p->ArrivalTime); p = p->link; } printf("\n----這組進程平均周轉時間:%f,平均帶權平均周轉時間:%f\n",avgRevolve/M,avgSuperRevolve/M); }
6》、刪除准備隊列(ready)已經運行的進程p ,添加到完成隊列(finish)隊列中
// 刪除准備隊列(ready)已經運行的進程p ,添加到完成隊列(finish)隊列中 void destory(pcb *p,int now_time) { pcb *q = ready; pcb *f = NULL; if(strcmp(p->name,ready->name) == 0) //第一個進程 { ready = ready ->link; } else //中間進程 { q = ready; while( (strcmp(q->link->name,p->name) != 0) && NULL != q->link) //找到p要刪除的位置 { q= q->link; } q->link = p->link; } //將已經運行的進程添加到finish隊列 p->StartTime = now_time-p->WholeTime; p->FinishTime = now_time; if(NULL == finish) //第一個完成的進程 { finish = p; p->link = NULL; } else //中間完成的進程 { f = finish; while(NULL != f->link ) { f = f->link; } f->link = p; p->link = NULL; } N--; //等待進程減1 }
int main() { input(); struct pcb *s = ready; int now_time = 0 ; struct pcb *nowProgress = NULL; //當前運行的進程 int *after = 0; //執行完一個進程之后的時間 int i = 0 ; pcb *m = ready; while(N > 0)//一次運行一個進程 { nowProgress = sjf(now_time,&after); if(NULL != nowProgress) //當前有進程在運行 { for(;now_time < after;now_time++) //輸出每個時刻運行的進程情況 { printf("#################################################\n"); printf("當前時刻:%d\n",now_time); printf("\n-------------當前執行進程:----------\n"); output(nowProgress,now_time); printf("\n-------------等待執行進程:----------\n"); m=ready; while(NULL != m) { if(m != nowProgress) { if(m->ArrivalTime <= now_time) output(m,now_time); } m= m->link; } printf("#################################################\n\n"); } printf("\n"); destory(nowProgress,now_time); } else //沒有進程在運行 { output(nowProgress,now_time); now_time ++; } } outputAll(); return 0; }



1.先來先服務(FCFS, First Come First Serve),按先后順序進行調度。
(1)、適用場景:
比較有利於長進程,而不利於短進程。因為長進程會長時間占據處理機。
有利於CPU繁忙的進程,而不利於I/O繁忙的進程。
(2)、優點:
有利於長進程,有利於等待時間久的進程,不會有進程長期等待而得不到響應。有利於CPU頻繁的進程。
(3)、缺點:
不利於短進程,忽視了進程的運行時間。不利於I/O頻繁的進程。
2. 響應比高者優先(HRN):FCFS和SJF的的折中,動態生成昨夜的優先級。
(1)、優點:
既考慮了進程的等待時間,又考慮了進程的運行時間,是FCFS和SJF的的折中,會考慮讓進程短的先進行,隨着長進程等待時間的增加,優先級相應的增加,使得通過一定時間的等待,必然有機會獲得處理機。
(2)、缺點:
在每次進行調度之前,都需要先做響應比的計算,會增加系統的開銷
3. 優先級法(Priority Scheduling):按照進程的優先級,對進程進程調度。
(1)、分類:
靜態優先級:
進程調度中的靜態優先級大多按以下原則確定:
由用戶自己根據進程的緊急程度輸入一個適當的優先級。
由系統或操作員根據進程類型指定優先級。
系統根據進程要求資源情況確定優先級。
進程的靜態優先級的確定原則:
按進程的類型給予不同的優先級。
將進程的情態優先級作為它所屬進程的優先級。
動態優先級:
進程的動態優先級一般根據以下原則確定:
根據進程占用有CPU時間的長短來決定。
根據就緒進程等待CPU的時間長短來決定。
(2)、優點:
可以通過優先級反映進程的緊迫程序,使比較緊迫的進程優先運行
(3)、缺點:
需要計算進程的優先級,會產生一定的開銷。
4.短進程優先法(SJF, Shortest Job First):短進程優先運行,其目標是減少平均周轉時間。
(1) 優點:
比FCFS改善平均周轉時間和平均帶權周轉時間,縮短進程的等待時間;
提高系統的吞吐量;
(2) 缺點:
對長進程非常不利,可能長時間得不到執行;
未能依據進程的緊迫程度來划分執行的優先級;
難以准確估計進程(進程)的執行時間,從而影響調度性能。
采用SJF算法時,人—機交互無法實現
完全未考慮進程的緊迫程度,故不能保證緊迫性進程得到及時處理