1. 程式人生 > >作業系統:先來先服務FCFS和短作業優先SJF程序排程演算法

作業系統:先來先服務FCFS和短作業優先SJF程序排程演算法

目的:陸續整理近一年的學習收穫

                               先來先服務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();  //遞迴
	}
}