Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Chương trình C++ cho lập lịch Shortest Job First (SJF) ưu tiên (preemptive)


Cho tiến trình, thời gian thực thi (burst time) của tiến trình tương ứng và giới hạn quantum; nhiệm vụ là tìm và in thời gian chờ, thời gian vòng tròn và thời gian trung bình tương ứng của chúng sử dụng phương pháp lập lịch Shortest Job First ưu tiên (preemptive).

Lập lịch Shortest Job First là gì?

Lập lịch Shortest Job First là thuật toán lập lịch công việc hoặc tiến trình tuân theo quy tắc lập lịch non-preemptive. Trong đó, bộ lập lịch chọn tiến trình từ hàng đợi chờ với thời gian hoàn thành ít nhất và cấp CPU cho công việc hoặc tiến trình đó. Shortest Job First ưu tiên hơn thuật toán FIFO vì SJF tối ưu hơn do giảm thời gian chờ trung bình, tăng thông lượng.

Thuật toán SJF có thể là preemptive cũng như non-preemptive. Lập lịch preemptive còn được gọi là shortest-remaining-time-first scheduling. Trong cách tiếp cận preemptive, tiến trình mới xuất hiện khi đã có tiến trình đang thực thi. Nếu burst time của tiến trình mới đến nhỏ hơn burst time của tiến trình đang thực thi thì bộ lập lịch sẽ ưu tiên thực thi tiến trình có burst time nhỏ hơn.

Turnaround time, waiting time và completion time là gì?

  • Completion Time là thời gian cần thiết để tiến trình hoàn thành thực thi.
  • Turnaround Time là khoảng thời gian giữa lúc nộp tiến trình và lúc hoàn thành.

    Turnaround Time = thời gian hoàn thành tiến trình – thời gian nộp tiến trình

  • Waiting Time là hiệu giữa turnaround time và burst time.

    Waiting Time = turnaround time – burst time

Ví dụ

Cho các tiến trình P1, P2, P3, P4, P5 với burst time tương ứng như bảng sau:

Tiến trình Burst Time Arrival Time
P1 4 0
P2 2 1
P3 8 2
P4 1 3
P5 9 4

Vì arrival time của P1 là 0 nên nó được thực thi đầu tiên cho đến khi tiến trình khác đến. Khi tại thời điểm 1, tiến trình P2 đến và burst time của P2 nhỏ hơn P1 nên bộ lập lịch sẽ phân phối CPU cho P2, và cứ thế.

Chương trình C++ cho lập lịch Shortest Job First (SJF) ưu tiên (preemptive)

Thời gian chờ trung bình tính dựa trên biểu đồ Gantt. P1 chờ (0+4)=4, P2 chờ 1, P3 chờ 7, P4 chờ 3, P5 chờ 15. Thời gian chờ trung bình:

Chương trình C++ cho lập lịch Shortest Job First (SJF) ưu tiên (preemptive)

Thuật toán

Bắt đầu
Bước 1 -> Khai báo struct Process
    Khai báo pid, bt, art
Bước 2 -> Trong hàm findTurnAroundTime(Process proc[], int n, int wt[], int tat[])
    Vòng lặp Với i = 0 đến i < n và i++
        Gán tat[i] = proc[i].bt + wt[i]
Bước 3 -> Trong hàm findWaitingTime(Process proc[], int n, int wt[])
    Khai báo rt[n]
    Vòng lặp Với i = 0 đến i < n và i++
        Gán rt[i] = proc[i].bt
        Gán complete = 0, t = 0, minm = INT_MAX
        Gán shortest = 0, finish_time
        Gán bool check = false
        Vòng lặp Khi (complete != n)
            Vòng lặp Với j = 0 đến j < n và j++
                NẾU (proc[j].art <= t) VÀ (rt[j] < minm) VÀ rt[j] > 0 thì,
                    Gán minm = rt[j]
                    Gán shortest = j
                    Gán check = true
            NẾU check == false thì,
                Tăng t lên 1
                Tiếp tục
            Kết thúc
            Giảm rt[shortest] đi 1
            Gán minm = rt[shortest]
            NẾU minm == 0 thì,
                Gán minm = INT_MAX
            Kết thúc
            NẾU rt[shortest] == 0 thì,
                Tăng complete lên 1
                Gán check = false
                Gán finish_time = t + 1
                Gán wt[shortest] = finish_time - proc[shortest].bt - proc[shortest].art
                NẾU wt[shortest] < 0
                    Gán wt[shortest] = 0
                Kết thúc
                Tăng t lên 1
Bước 4 -> Trong hàm findavgTime(Process proc[], int n)
    Khai báo và gán wt[n], tat[n], total_wt = 0, total_tat = 0
    Gọi findWaitingTime(proc, n, wt)
    Gọi findTurnAroundTime(proc, n, wt, tat)
    Vòng lặp Với i = 0 đến i < n và i++
        Gán total_wt = total_wt + wt[i]
        Gán total_tat = total_tat + tat[i]
        In proc[i].pid, proc[i].bt, wt[i], tat[i]
        In thời gian chờ trung bình: total_wt / n
        In thời gian vòng tròn trung bình: total_tat / n
Bước 5 -> Trong hàm int main()
    Khai báo và gán Process proc[] = {{1, 5, 1}, {2, 3, 1}, {3, 6, 2}, {4, 5, 3}}
    Gán n = sizeof(proc) / sizeof(proc[0])
    Gọi findavgTime(proc, n)
Kết thúc

Ví dụ mã C++

#include <bits/stdc++.h>
using namespace std;

// Cấu trúc cho mỗi tiến trình
struct Process {
    int pid; // ID tiến trình
    int bt;  // Burst Time
    int art; // Arrival Time
};

void findTurnAroundTime(Process proc[], int n, int wt[], int tat[]) {
    for (int i = 0; i < n; i++)
        tat[i] = proc[i].bt + wt[i];
}

// Thời gian chờ của tất cả tiến trình
void findWaitingTime(Process proc[], int n, int wt[]) {
    int rt[n];
    for (int i = 0; i < n; i++)
        rt[i] = proc[i].bt;
    int complete = 0, t = 0, minm = INT_MAX;
    int shortest = 0, finish_time;
    bool check = false;
    while (complete != n) {
        for (int j = 0; j < n; j++) {
            if ((proc[j].art <= t) && (rt[j] < minm) && rt[j] > 0) {
                minm = rt[j];
                shortest = j;
                check = true;
            }
        }
        if (check == false) {
            t++;
            continue;
        }
        // giảm thời gian còn lại
        rt[shortest]--;
        minm = rt[shortest];
        if (minm == 0)
            minm = INT_MAX;
        // Nếu tiến trình hoàn thành hoàn toàn
        if (rt[shortest] == 0) {
            complete++;
            check = false;
            finish_time = t + 1;
            // Tính thời gian chờ
            wt[shortest] = finish_time - proc[shortest].bt - proc[shortest].art;
            if (wt[shortest] < 0)
                wt[shortest] = 0;
        }
        // Tăng thời gian
        t++;
    }
}

// Hàm tính thời gian trung bình
void findavgTime(Process proc[], int n) {
    int wt[n], tat[n], total_wt = 0, total_tat = 0;
    // Tìm thời gian chờ của tất cả tiến trình
    findWaitingTime(proc, n, wt);
    // Tìm thời gian vòng tròn cho tất cả tiến trình
    findTurnAroundTime(proc, n, wt, tat);
    cout << "Tiến trình " << " Burst time " << " Waiting time " << " Turn around time\n";
    for (int i = 0; i < n; i++) {
        total_wt = total_wt + wt[i];
        total_tat = total_tat + tat[i];
        cout << " " << proc[i].pid << "\t\t" << proc[i].bt << "\t\t " << wt[i] << "\t\t " << tat[i] << endl;
    }
    cout << "\nThời gian chờ trung bình = " << (float)total_wt / (float)n;
    cout << "\nThời gian vòng tròn trung bình = " << (float)total_tat / (float)n;
}

// Hàm main
int main() {
    Process proc[] = {{1, 5, 1}, {2, 3, 1}, {3, 6, 2}, {4, 5, 3}};
    int n = sizeof(proc) / sizeof(proc[0]);
    findavgTime(proc, n);
    return 0;
}

Đầu ra

Chương trình C++ cho lập lịch Shortest Job First (SJF) ưu tiên (preemptive)