作業系統:先來先服務FCFS和短作業優先SJF程序排程演算法
阿新 • • 發佈:2018-12-09
目的:陸續整理近一年的學習收穫
先來先服務FCFS和短作業優先SJF程序排程演算法
一:概念
- 先來先服務FCFS排程演算法:最簡單的排程演算法,既可以用於作業排程 ,也可以用於程式排程,當作業排程中採用該演算法時,系統將按照作業到達的先後次序來進行排程,優先從後備佇列中,選擇一個或多個位於佇列頭部的作業,把他們調入記憶體,分配所需資源、建立程序,然後放入“就緒佇列”,直到該程序執行到完成或發生某事件堵塞後,程序排程程式才將處理機分配給其他程序。
有利於長作業(程序)而不利於短作業(程序)
有利於CPU繁忙型作業(程序)而不利於I/O繁忙型作業(程序)
- 短作業優先SJF程序排程演算法:以作業長短來確定優先順序,作業越短優先順序越高,作業的長短用作業所需的執行時間來衡量,此演算法一樣也可以用做程序排程,它將從外存的作業後備佇列中選擇若干個估計執行時間最短的作業,優先將它們調入記憶體執行
比FCFS改善平均週轉時間和平均帶權週轉時間,縮短作業的等待時間;
對長作業非常不利,可能長時間得不到執行;
未能依據作業的緊迫程度來劃分執行的優先順序;
難以準確估計作業(程序)的執行時間,從而影響排程效能。
二:程式設計
- 定義程序結構體
typedef struct{ char ID;//程序名字 int ArrivalTime;//到達時間 int ServiceTime;//服務時間 int FinishTime;//完成時間 int ExecuteTime;//各程序的開始執行時間 int WholeTime;//週轉時間 double WeightWholeTime;//帶權週轉時間 }PRO;
- 主要函式
void Input();//輸入程序數、各程序到達、服務時間
void sortArrivalTime();//根據達時間排序
void sortServiceTime();//已到達的程序服務時間排序
void calculationInitTime(int i);//計算第一個程序的各個時間
void calculationTime(int i);//計算
void display(int b);//輸出
void outTimeState(int b);//輸出各時間狀態
void chooseAlgorithm();//選擇演算法
void FCFS();
void SJF();
- 演算法詳細設計
FCFS:
void FCFS(){
int i;
//根據達時間排序
sortArrivalTime();
//FCFS計算各時間
calculationInitTime(0);
for(i=1;i<n;i++) {
calculationTime(i);
SumWT_FCFS += pro[i].WholeTime;
SumWWT_FCFS += pro[i].WeightWholeTime;
}
SumWT_FCFS += pro[0].WholeTime;
SumWWT_FCFS += pro[0].WeightWholeTime;
AverageWT_FCFS = (double)SumWT_FCFS/(double)n;
AverageWWT_FCFS = (double)SumWWT_FCFS/(double)n;
//FCFS輸出各時間
display(n);
//FCFS輸出各時間狀態
outTimeState(n);
}
SJF:
void SJF(){
int i;
//根據達時間排序
sortArrivalTime();
//SJF計算各時間
calculationInitTime(0);
for(i=1;i<n;i++) {
sortServiceTime();
calculationTime(i);
SumWT_SJF += pro[i].WholeTime;
SumWWT_SJF += pro[i].WeightWholeTime;
}
SumWT_SJF += pro[0].WholeTime;
SumWWT_SJF += pro[0].WeightWholeTime;
AverageWT_SJF = (double)SumWT_SJF/(double)n;
AverageWWT_SJF = (double)SumWWT_SJF/(double)n;
//SJF輸出各時間
display(n);
//SJF輸出各時間狀態
outTimeState(n);
}
三:實驗結果
FCFS
SJF
四:實驗原始碼
#include <iostream>
#include <iomanip>
using namespace std;
#define MaxNum 100//允許的最大程序數
typedef struct{
char ID;//程序名字
int ArrivalTime;//到達時間
int ServiceTime;//服務時間
int FinishTime;//完成時間
int ExecuteTime;//各程序的開始執行時間
int WholeTime;//週轉時間
double WeightWholeTime;//帶權週轉時間
}PRO;
static int n=0;//程序數
static PRO pro[100]; //程序結構體
static PRO temp; //程序結構
static int choose;//演算法選擇
static double AverageWT_FCFS=0,AverageWT_SJF=0;//FCFS和SJF的平均週轉時間
static double AverageWWT_FCFS=0,AverageWWT_SJF=0;//FCFS和SJF的平均帶權週轉時間
static int SumWT_FCFS=0,SumWT_SJF=0;//FCFS、SJF中的週轉時間總和
static double SumWWT_FCFS=0,SumWWT_SJF=0;;//FCFS、SJF中的帶權週轉時間總和
void Input();//輸入程序數、各程序到達、服務時間
void sortArrivalTime();//根據達時間排序
void sortServiceTime();//已到達的程序服務時間排序
void calculationInitTime(int i);//計算第一個程序的各個時間
void calculationTime(int i);//計算
void display(int b);//輸出
void outTimeState(int b);//輸出各時間狀態
void chooseAlgorithm();//選擇演算法
void FCFS();
void SJF();
int main(){
int i,j;
//初始化
for(i=0;i<MaxNum;i++) {
pro[i].ID = i+65;//自動將程序名字順序編號為A、B、C、D、E等
}
Input();
chooseAlgorithm();
return 0;
}
//輸入程序數、各程序到達、服務時間
void Input() {
cout<<"請輸入作業(程序)個數n:";
cin>>n;
cout<<"請分別輸入每個程序的到達時間(空格隔開):"<<endl;
for (int i=0;i<n;i++)
{
cin>>pro[i].ArrivalTime;
}
cout<<"請分別輸入每個程序的服務時間(空格隔開):"<<endl;
for (int i=0;i<n;i++)
{
cin>>pro[i].ServiceTime;
}
cout<<endl<<"------------------------------------"<<endl;
}
//根據達時間排序
void sortArrivalTime() {
int i,j;
for(i=0;i<n;i++) {
for(j=i+1;j<n;j++) {
if(pro[i].ArrivalTime > pro[j].ArrivalTime) {
temp = pro[i];
pro[i] = pro[j];
pro[j] = temp;
}
}
}
}
//已到達的程序服務時間排序
void sortServiceTime() {
int i,j;
for(i=1;i<n;i++) {
for(j=i+1;j<n;j++) {
if(pro[i].ServiceTime > pro[j].ServiceTime) {
temp = pro[i];
pro[i] = pro[j];
pro[j] = temp;
}
}
}
}
//計算第一個程序的各個時間
void calculationInitTime( int i) {
pro[i].FinishTime = pro[i].ArrivalTime + pro[i].ServiceTime;
pro[i].WholeTime = pro[i].FinishTime- pro[i].ArrivalTime;
pro[i].WeightWholeTime = (double)pro[i].WholeTime/(double)pro[i].ServiceTime;
pro[i].ExecuteTime = pro[i].ArrivalTime;
}
//計算完成時間、週轉時間、帶權週轉時間、開始執行時間
void calculationTime(int i) {
if(pro[i].ArrivalTime <= pro[i-1].FinishTime) {
pro[i].FinishTime = pro[i-1].FinishTime + pro[i].ServiceTime;
pro[i].ExecuteTime = pro[i-1].FinishTime;
}
else {
pro[i].FinishTime= pro[i].ArrivalTime + pro[i].ServiceTime;
pro[i].ExecuteTime= pro[i].ArrivalTime;
}
pro[i].WholeTime = pro[i].FinishTime - pro[i].ArrivalTime;
pro[i].WeightWholeTime = (double)pro[i].WholeTime/(double)pro[i].ServiceTime;
}
//輸出ID、到達時間、服務時間、完成時間、週轉時間、帶權週轉時間、開始執行時間、週轉時間總和、帶權週轉時間總和、平均週轉時間、平均帶權週轉時間
void display(int b) {
cout<<"ID"<<"\t"<<"到達時間"<<"\t"<<"服務時間"<<"\t"<<"完成時間"<<"\t"<<"週轉時間"<<"\t"<<"帶權週轉時間"<<"\t"<<"開始執行時間"<<endl;
int i;
for(i=0;i<b;i++) {
cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t";
cout<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<"\t"<<"\t"<<pro[i].ExecuteTime<<endl;
}
if(choose==1){
cout<<endl<<"FCFS週轉時間總和: "<<SumWT_FCFS<<endl<<"FCFS帶權週轉時間總和: ";
cout<<SumWWT_FCFS<<endl<<"FCFS平均週轉時間: ";
cout<<AverageWT_FCFS<<endl<<"FCFS帶權平均週轉時間: ";
cout<<AverageWWT_FCFS<<endl;
}
else{
cout<<endl<<"SJF週轉時間總和: "<<SumWT_SJF<<endl<<"SJF帶權週轉時間總和: ";
cout<<SumWWT_SJF<<endl<<"SJF平均週轉時間: ";
cout<<AverageWT_SJF<<endl<<"SJF帶權平均週轉時間: ";
cout<<AverageWWT_SJF<<endl;
}
}
//輸出各時間狀態
void outTimeState(int b) {
int i,j;
cout<<endl;
for(i=0;i<=pro[b-1].FinishTime;i++) {
cout<<"時刻 "<<i<<": ";
for(j=0;j<b;j++) {
if(pro[j].ArrivalTime == i && pro[j].ExecuteTime== i)
cout<<"ID "<<pro[j].ID<<" 程序到達並且執行, ";
else if(pro[j].ArrivalTime == i)
cout<<"ID "<<pro[j].ID<<" 到達, ";
else if(pro[j].ExecuteTime == i)
cout<<"ID "<<pro[j].ID<<" 開始執行, ";
else if(pro[j].FinishTime == i)
cout<<"ID "<<pro[j].ID<<" 完成, ";
}
cout<<endl;
}
}
void FCFS(){
int i;
//根據達時間排序
sortArrivalTime();
//FCFS計算各時間
calculationInitTime(0);
for(i=1;i<n;i++) {
calculationTime(i);
SumWT_FCFS += pro[i].WholeTime;
SumWWT_FCFS += pro[i].WeightWholeTime;
}
SumWT_FCFS += pro[0].WholeTime;
SumWWT_FCFS += pro[0].WeightWholeTime;
AverageWT_FCFS = (double)SumWT_FCFS/(double)n;
AverageWWT_FCFS = (double)SumWWT_FCFS/(double)n;
//FCFS輸出各時間
display(n);
//FCFS輸出各時間狀態
outTimeState(n);
}
void SJF(){
int i;
//根據達時間排序
sortArrivalTime();
//SJF計算各時間
calculationInitTime(0);
for(i=1;i<n;i++) {
sortServiceTime();
calculationTime(i);
SumWT_SJF += pro[i].WholeTime;
SumWWT_SJF += pro[i].WeightWholeTime;
}
SumWT_SJF += pro[0].WholeTime;
SumWWT_SJF += pro[0].WeightWholeTime;
AverageWT_SJF = (double)SumWT_SJF/(double)n;
AverageWWT_SJF = (double)SumWWT_SJF/(double)n;
//SJF輸出各時間
display(n);
//SJF輸出各時間狀態
outTimeState(n);
}
void chooseAlgorithm()
{
cout<<"請選擇演算法“1-FCFS,2-SJF”"<<endl;
cin>>choose;
cout<<endl;
if (choose==1)
{
FCFS();
}
else if(choose==2)
{
SJF();
}
else
{
cout<<"請輸入正確的選擇“1-FCFS,2-SJF”"<<endl;
cout<<"------------------------------------"<<endl;
chooseAlgorithm(); //遞迴
}
}