操作系統調度算法-HRRN高優先級調度算法


高優先級調度算法:

算法思想

按照優先級(等待時間 + 要求服務時間) / 要求服務時間進行排序,總是運行優先級最高的進程不可搶占,只有當前進程運行完了才考慮其他進程的運行。

優缺點

綜合考慮了等待時間換運行時間(要求時間),等待時間相同時,要求服務時間短的優先(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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM