處理機的調度

1  處理機的調度層次和調度算法目標

2 批處理系統中的作業調度

2.1 先來先服務調度算法(first-come first-served,FCFS)

描述:FCFS是最簡單的調度算法,該算法可用於作業調度,也可用於進程調度,當在作業調度中採用該算法時,系統將按照作業到達的先後次序進行調度,或者說優先考慮在系統中等待時間最長的作業,而不管作業需要執行時間的長短,從後背作業隊列中選擇幾個最先進入該隊列的作業,將他們調入內存,爲他們分配資源和創建進程,最後放入就緒隊列。

當在進程中採用該算法時,每次調度從就緒的進程隊列中選擇一個最先進入該隊列的進程,爲之分配處理機,投入運行。該進程一直運行到完成或者發生某個時間阻塞時,進程調度將處理機分配給其他進程。

算法實現:

// Fsc.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#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"<< "週轉時間\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\t";
		}
		cout << endl;
	}
}

2.2 短作業優先調度算法(short job first,SJF)

SJF算法是以作業的長短來計算優先級,作業越短優先級越高,作業長短是以作業運行時間長短來衡量。SJF算法可以分別用於作業調度和進程調度,再把短作業優先調度算法用於作業調度時,它將外存的作業後背隊列中選擇若干個估計運行時間最短的作業,優先將他們調入內存。

缺點:

(1)必須預知作業的運行時間,但一般很難預測每個作業運行時間的長短,如果預計過低,系統就可能按估計時間終止作業的運行,但此時作業未完成,所以一般偏長估計。

(2)對長作業不利,長作業週轉時間明顯變長,該算法完全忽視作業等待時間,可能使作業等待時間過長,出現飢餓現象。

(3)採用SJF算法時,人機無法交互。

(4)該算法沒有考慮作業的緊迫程度,所以不能保證緊迫的作業得到及時處理。

算法實現:

#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;
	}
	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;
				break;
			}
		}
	}
	for (int i = 0;i < processNumber;i++)
	{
		array[i][0] = i + 1;
	}
	cout << "進程號\t" << "開始時間\t" <<"運行時間\t"<<"完成時間\t"<<"週轉時間\t"<< endl;
	for (int i = 0;i < processNumber;i++)
	{
		for (int j = 0;j < 5;j++)
			cout << array[i][j] << " \t\t";
		cout << endl;
	}

}

2.3 優先級調度算法和高響應比優先調度算法(Heigest Response Ratio Next,HRRN)

我們可以這樣理解優先級,對於先來先服務算法,作業的等待時間就是其優先級,等待時間越長,優先級越高。對於短作業調度算法,作業所需運行時間越短優先級越高。

在批處理系統中,短作業優先算法是一種比較好的算法,其主要的不足之處是長作業 的運行得不到保證。如果我們能爲每個作業引入前面所述的動態優先權,並使作業的優先 級隨着等待時間的增加而以速率 a 提高,則長作業在等待一定的時間後,必然有機會分配 到處理機。該優先權的變化規律可描述爲:

優先權=(要求服務時間 等待時間)/ 要求服務時間  , 由於等待時間與服務時間之和就是系統對該作業的響應時間,故該優先權又相當於響 應比 RP。據此,又可表示爲:

RP=(要求服務時間 等待時間)/ 要求服務時間 =  響應時間 /要求服務時間 , 由上式可以看出:

(1) 如果作業的等待時間相同,則要求服務的時間愈短,其優先權愈高,因而該算法有 利於短作業。

(2) 當要求服務的時間相同時,作業的優先權決定於其等待時間,等待時間愈長,其優 先權愈高,因而它實現的是先來先服務。 (3) 對於長作業,作業的優先級可以隨等待時間的增加而提高,當其等待時間足夠長時, 其優先級便可升到很高,從而也可獲得處理機。 簡言之,該算法既照顧了短作業,又考慮了作業到達的先後次序,不會使長作業長期 得不到服務。因此,該算法實現了一種較好的折衷。當然,在利用該算法時,每要進行調 第三章 處理機調度與死鎖 ·95· 度之前,都須先做響應比的計算,這會增加系統開銷。

#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;

	}
}

 

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