高優先級調度算法:
算法思想
按照優先級(等待時間 + 要求服務時間) / 要求服務時間進行排序,總是運行優先級最高的進程不可搶占,只有當前進程運行完了才考慮其他進程的運行。
優缺點
綜合考慮了等待時間換運行時間(要求時間),等待時間相同時,要求服務時間短的優先(SJF的優點);要求服務時間相同時,等待時間長的優先(FCFS的優點),隨着等待時間越來越長,響應比也會越來越大,避免了長作業飢餓的問題。
代碼
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <vector>
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
using namespace std;
const int N = 1e5 + 10;
enum Status{running, ready, blocked, finished};
string status[] = { "running", "ready", "blocked", "finished"};
int n;
struct PCB//程序控制塊
{
string id;
int startblock;//到達時間
int alltime;//總時間
int blocktime;//阻塞時間
int cputime;//運行時間
int starttime;
int end_time;//結束時間
int turnover_time;//周轉時間
double response_ratio;//優先級
Status state;//進程狀態
struct PCB* next;
} P[N];
bool operator < (PCB a, PCB b) {//重載小於號 按照進程剩余時間進行排序
if (a.state == finished)return 1;
else if (b.state == finished)return 1;
return a.alltime - a.cputime > b.alltime - b.cputime;
}
bool cmp1( PCB& p1, PCB& p2)//按照到達時間從小到大排序,到達時間一樣按照總時間從小到大排序
{
if (p1.startblock == p2.startblock)
return p1.alltime < p2.alltime;
return p1.startblock < p2.startblock;
}
void setstarttime(string id, int starttime, PCB* l);
bool cmp2(PCB& p1, PCB& p2)//按照優先級從大到小排序 優先級一樣按照開始時間從大到小排序
{
return (p1.response_ratio > p2.response_ratio) || (p1.response_ratio == p2.response_ratio && p1.startblock < p2.startblock);
}
void display(PCB* p);
void HRRN(PCB* p)//HRRN高優先級調度算法
{
string sequence = "";//程序運行序列
int i, j, now;
now = 0, j = 0;
sort(p, p + n, cmp1);
for (i = 0; i <= n; i++)
{
while (j < n && p[j].startblock <= now) {//找當前已經到達的所有進程
p[j++].state = ready;
}
for (int k = j + 1; k < n; k++)p[k].state = blocked;
for (int k = i; k < j; k++)
p[k].response_ratio = (now - p[k].startblock + p[k].alltime) / p[k].alltime; //重新計算優先級 i~j
sort(p + i, p + j, cmp2);//按優先級排序
//優先級最高的程序已經到達隊首,運行隊首程序,更改隊首程序參數
if (p[i].startblock > now)//當前時間還沒有到該進程的到達時間
p[i].end_time = p[i].startblock + p[i].alltime;
else //到該進程已經到達
p[i].end_time = now + p[i].alltime;
p[i].state = running;//設置狀態
sequence += p[i].id;
setstarttime(p[i].id, now, p);
p[i].turnover_time = p[i].end_time - p[i].startblock;
now = p[i].end_time;
if (i)p[i - 1].state = finished, p[i - 1].cputime = p[i - 1].alltime;
else if (i == n - 1)p[i].state = finished, p[i].cputime = p[i].alltime;
display(p);
}
cout << "程序的運行序列(HRRN算法):";
for (int i = 0; i < (int)sequence.size(); i++) {
if (i != (int)sequence.size() - 1) cout << sequence[i] << "->";
else cout << sequence[i];
}
cout << endl;
}
void setPCB(PCB p, PCB *l) {//設置PCB運行時間,結束時間,狀態
for (int i = 0; i < n; i++) {
if (l[i].id == p.id) {
l[i].cputime = p.cputime;
l[i].end_time = p.end_time;
l[i].state = p.state;
return;
}
}
}
void setState(string id, Status st, PCB* l) {//設置PCB控制塊的狀態
for (int i = 0; i < n; i++) {
if (l[i].id == id) {
l[i].state = st;
return ;
}
}
}
void setstarttime(string id, int starttime, PCB* l) {//設置進程開始時間
for (int i = 0; i < n; i++) {
if (l[i].id == id) {
l[i].starttime = starttime;
return;
}
}
}
void SRTF(PCB *p) {//最短剩余時間優先算法
string sequence = "";//程序運行序列
int j = 0;// 當前時間
priority_queue<PCB>arr;//已經就緒的進程隊列
queue<PCB> q;//進程總隊列
sort(p, p + n, cmp1);//按照到達時間排序
for (int i = 0; i < n; i++)q.push(p[i]);
int now = -1;
int solve = 0;
while (1) {
++now;
cout << "當前時間:" << now << endl;
bool flag = 0;
//每當當前有任務到達時,重新排序未執行完的進程的剩余時間
while (q.size() && q.front().startblock <= now) {//找到當前已經到達的任務
PCB a = q.front();
setState(a.id, ready, p);
arr.push(a);
q.pop();
flag = 1;
}
PCB a = arr.top();
arr.pop();
//運行當前程序,更改當前程序參數
if(a.cputime == 0)setstarttime(a.id, now, p);
a.end_time = now;
a.cputime = min(a.cputime + 1, a.alltime);//運行時間 + 1
a.state = running;
sequence += a.id;
setPCB(a, p);
if(a.cputime >= a.alltime){//當前任務已經運行完成 設置對應參數
setState(a.id, finished, p);
solve++;
}
display(p);
if (a.cputime < a.alltime) {//還沒有運行完
setState(a.id, ready, p);
arr.push(a);
}
if (solve >= n)break;
}
char temp = sequence[0];
cout << "程序的運行序列(SRTF算法):";
cout << temp << ' ';
for (int i = 1; i < (int)sequence.size(); i++) {
if (temp != sequence[i]) {
cout << sequence[i] << ' ';
}
temp = sequence[i];
}
cout << endl;
}
void display(PCB *p) {//輸出進程調度情況
double sum = 0;
cout << "進程名稱\t" << "到達系統時間\t" << "所需服務時間\t" << "開始時間\t" << "結束時間\t" << "已經服務時間\t" << "狀態" << endl;
for (int i = 0; i < n; i++)
{
cout << p[i].id << "\t\t" << p[i].startblock << "\t\t" << p[i].alltime << "\t\t" << p[i].starttime << "\t\t" << p[i].end_time << "\t\t" << p[i].cputime << "\t\t" << status[p[i].state] << endl;
sum += p[i].turnover_time;
}
//cout << "平均周轉時間: " << sum / n << endl;
}
int main()
{
n = 5;
ios::sync_with_stdio(0);
freopen("a.txt", "r", stdin);
cout << "請輸入五個進程的名稱, 開始時間,要求服務時間:\n";
for (int i = 0; i < n; i++) {
cin >> P[i].id >> P[i].startblock >> P[i].alltime;
P[i].state = blocked;
}
HRRN(P);
return 0;
}