先來先服務調度算法&短時間調度算法&高優先權調度算法

目錄

一 ,先來先服務的調度算法

1.1 優缺點

二,最短作業優先算法SJF

2.1 SJF算法的優缺點:

2.2 SJF調度算法的問題:

三,高優先級調度算法

3.1 優先級調度的含義

3.2 調度算法的兩種方式

3.3 優先級的類型

3.4 靜態優先級

3.5 動態優先級


一 ,先來先服務的調度算法

最簡單的調度算法,既可以用於作業調度 ,也可以用於程序調度,當作業調度中採用該算法時,系統將按照作業到達的先後次序來進行調度,優先從後備隊列中,選擇一個或多個位於隊列頭部的作業,把他們調入內存,分配所需資源、創建進程,然後放入“就緒隊列”,直到該進程運行到完成或發生某事件堵塞後,進程調度程序纔將處理機分配給其他進程。

1.1 優缺點

有利於長作業(進程)而不利於短作業(進程)

有利於CPU繁忙型作業(進程)而不利於I/O繁忙型作業(進程)

#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
	int countHomework;
	cout << "請輸入作業數量:" << endl;
	cin >> countHomework;
	double **arr = new double *[countHomework];
	for (int i = 0;i < countHomework;i++)
	{
		arr[i] = new double[5];
	}
	for (int i = 0;i < countHomework;i++)//初始化
		for (int j = 0;j < 5;j++)
			arr[i][j] = 0;
	double starttime, endtime;
	cout << "請輸入開始時間和運行時間" << endl;
	for (int i = 0;i < countHomework;i++) {
			cin >> starttime >> endtime;
			arr[i][1] = starttime;
			arr[i][2] = endtime;
	}
		double temp_1;
	double temp_2;
	for (int i = 0;i < countHomework;i++)
	{
		for (int j = i + 1;j < countHomework;j++)
		{
			if (arr[i][1] > arr[j][1])
			{
				temp_1 = arr[i][1];
				temp_2 = arr[i][2];
				arr[i][1] = arr[j][1];
				arr[i][2] = arr[j][2];
				arr[j][1] = temp_1;
				arr[j][2] = temp_2;
			}
		}
	}
	double currentTime;
	currentTime = arr[0][1];
	arr[0][3] = currentTime+arr[0][2];
	currentTime = arr[0][3];
	arr[0][4] = currentTime-arr[0][1];
	for (int i = 1;i < countHomework;i++)
	{
		arr[i][3] = currentTime + arr[i][2];
		currentTime += arr[i][2];
		arr[i][4] = currentTime - arr[i][1];//計算週轉時間
	}
	cout << "進程號\t" << "開始時間\t" << "運行時間\t" << "週轉時間\t" << endl;
	for (int i = 0;i < countHomework;i++) {
		arr[i][0] = i + 1;
		for (int j = 0;j < 5;j++)
		{
			cout << arr[i][j] << "\t";
		}
		cout << endl;
	}
}

二,最短作業優先算法SJF

SJF算法以進入系統的作業所要求的CPU時間爲標準,是指對短作業或者短進程優先調度的算法,將每個進程與其估計運行時間進行關聯選取估計計算時間最短的作業投入運行。

2.1 SJF算法的優缺點:

算法易於實現。但效率不高,主要弱點是忽視了作業等待時間;會出現飢餓現象。

SJF算法與FCFS算法的比較:

SJF的平均作業waiting time比FCFS要小,故它的調度性能比FCFS好。

2.2 SJF調度算法的問題:

實現SJF調度算法需要知道作業所需運行時間,否則調度就沒有依據,要精確知道一個作業的運行時間是辦不到的。

SJF是一種Non-preemptive(非搶佔試)調度。

與SJF類似的一種preemptive 版本的調度叫shortest-remaining-time-first。

SJF是一種優先調度(priority scheduling),優先的是inverse of 預測的下一個中央處理器突發時間。

SJF調度算法是被證明了的最佳調度算法,這是因爲對於給定的一組進程,SJF算法的平均週轉時間最小。通過將短進程移到長進程之前,短進程等待時間的減少大於長進程等特時間的增加,因此,平均等特時間減少了。

#include"pch.h"
#include<iostream>
using namespace std;
int main()
{
	int jobNum = 0;
	cout << "請輸入作業數量" << endl;
	cin >> jobNum;
	double **arr = new double*[jobNum];
	for (int i = 0;i < jobNum;i++)
	{
		arr[i] = new double[5];
	}
	for (int i = 0;i < jobNum;i++)
		for (int j = 0;j < 5;j++)
			arr[i][j] = 0;
	double startTime = 0, runningTime = 0;
	cout << "請輸入開始時間和運行時間" << endl;
	for (int i = 0;i < jobNum;i++)
	{
		cin >> startTime >> runningTime;
		arr[i][1] = startTime;
		arr[i][2] = runningTime;
		arr[i][0] = 0;
	}
	double currentTime = arr[0][1];
	arr[0][3] = arr[0][1] + arr[0][2];
	currentTime = arr[0][3];
	
	arr[0][4] = currentTime - arr[0][1];
    cout << currentTime << endl;	arr[0][0] = 1;
	int count = 1;
	double priority = 0;//定義優先級
	while (count < jobNum)
	{
		int i_job = 0;
		double maxPriority = 0;
		for (int i = 1;i < jobNum ;i++) 
		{
			if ((arr[i][0] != 1) && (arr[i][1] < currentTime)) {
				priority = (currentTime - arr[i][1] + arr[i][2]) / (arr[i][2]);//求出優先級
				if (maxPriority < priority) {
					maxPriority = priority;
					i_job = i;
				}
			}
		}
		arr[i_job][3] = arr[i_job][2]+currentTime;
		currentTime += arr[i_job][2];
		arr[i_job][4] = currentTime - arr[i_job][1];/
		arr[i_job][0] = 1;
		count++;
	}
	cout << "作業號\t" << "開始時間\t" << "運行時間\t" << "結束時間\t" << "週轉時間" << "\t" << endl;
	for (int i = 0;i < jobNum;i++)
	{
		arr[i][0] = i + 1;
		cout << arr[i][0] << "\t\t" << arr[i][1] << "\t\t" << arr[i][2] << "\t\t" << arr[i][3] << "\t\t" << arr[i][4] << "\t\t" << endl;

	}
}

三,高優先級調度算法

3.1 優先級調度的含義

(1)當該算法用於作業調度時,系統從後備作業隊列中選擇若干個優先級最高的,且系統能滿足資源要求的作業裝入內存運行。

(2)當該算法用於進程調度時,將把處理機分配給就緒進程隊列中優先級最高的進程。

3.2 調度算法的兩種方式

優先級調度算法細分成如下兩種方式:

非搶佔式優先級算法

在這種調度方式下,系統一旦把處理機分配給就緒隊列中優先級最高的進程後,該進程就能一直執行下去,直至完成;或因等待某事件的發生使該進程不得不放棄處理機時,系統才能將處理機分配給另一個優先級高的就緒進程。

搶佔式優先級調度算法

在這種調度方式下,進程調度程序把處理機分配給當時優先級最高的就緒進程,使之執行。一旦出現了另一個優先級更高的就緒進程時,進程調度程序就停止正在執行的進程,將處理機分配給新出現的優先級最高的就緒進程。

3.3 優先級的類型

進程的優先級可採用靜態優先級和動態優先級兩種,優先級可由用戶自定或由系統確定。

3.4 靜態優先級

(1)含義

靜態優先級是在創建進程時確定進程的優先級,並且規定它在進程的整個運行期間保持不變。

(2)確定優先級的依據(確定優先級的依據通常有下面幾個方面)

①進程的類型。通常系統進程優先級高於一般用戶進程的優先級;交互型的用戶進程的優先級高於批處理作業所對應的進程的優先級。

②進程對資源的需求。例如,進程的估計執行時間及內存需求量少的進程,應賦於較高的優先級,這有利縮小作業的平均週轉時間。

③根據用戶的要求。用戶可以根據自己作業的緊迫程度來指定一個合適的優先級。

(3)優缺點

靜態優先級法的優點是

①簡單易行 ②系統開銷小。

缺點是

①不太靈活,很可能出現低優先級的作業(進程),長期得不到調度而等待的情況。

②靜態優先級法僅適用於實時要求不太高的系統。

3.5 動態優先級

(1)含義

動態優先級是在創建進程時賦予該進程一個初始優先級,然後其優先級隨着進程的執行情況的變化而改變,以便獲得更好的調度性能。

(2)優缺點

動態優先級優點是使相應的優先級調度算法比較靈活、科學,可防止有些進程一直得不到調度,也可防止有些進程長期壟斷處理機。動態優先級缺點是需要花費相當多的執行程序時間,因而花費的系統開銷比較大。

(此算法是根據進程運行時間以及等待時間來確定優先級)

#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
	cout << "請輸入進程個數:" << endl;
	int processNumber;
	cin >> processNumber;
	double **array = new double*[processNumber];
	for (int i = 0;i < processNumber;i++)//申請空間
	{
		array[i] = new double[5];
	}
	for (int i = 0;i < processNumber;i++)//初始化
	{
		for (int j = 1;j < 5;j++)
			array[i][j] = 0;
		//array[i][0] = 0;
	}
	double startTime = 0.0, endTime = 0.0;
	cout << "請輸入每個進程到達時間和執行時間:" << endl;
	for (int i = 0;i < processNumber;i++) { 
		cin >> startTime >> endTime;
		array[i][1] = startTime;
		array[i][2] = endTime;
	}
	double currentTime = array[0][1];	
       array[0][3] = currentTime + array[0][2];
	currentTime += array[0][2];
	array[0][4] = currentTime - array[0][1];
	array[0][0] = 1;
	double temp = 0;
	for (int i = 1;i < processNumber;i++)
	{
		for (int j = i + 1;j < processNumber;j++)
		{
			if (array[i][2] > array[j][2])
			{
				temp = array[i][2];
				array[i][2] = array[j][2];
				array[j][2] = temp;
				temp = array[i][1];
				array[i][1] = array[j][1];
				array[j][1] = temp;
			}
		}
	}
	int count = 1;
	while (count < processNumber) {
		for (int i = 1;i < processNumber;i++)
		{
			if (array[i][1] < currentTime&&array[i][0] != 1)
			{
				currentTime += array[i][2];
				array[i][3] = currentTime;//填入進程完成時間
				array[i][4] = currentTime - array[i][1];//週轉時間
				count++;
				array[i][0] = 1;
			}
		}
	}
	for (int i = 0;i < processNumber;i++)
	{
		array[i][0] = i + 1;
	}
	cout << "進程號\t" << "開始時間\t" <<"運行時間\t"<<"週轉時間\t"<< endl;
	for (int i = 0;i < processNumber;i++)
	{
		for (int j = 0;j < 5;j++)
			cout << array[i][j] << " \t";
		cout << endl;
	}

}

歡迎各位指出不足,以便以後更加完善,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章