Shortest Job First (SJF) スケジューリングのプリエンプティブ バージョンは、Shortest Remaining Time First (SRTF) と呼ばれます。 SRTF では、終了までの残り時間が最も短いプロセスが選択されて実行されます。実行中のプロセスは、終了するか、残り時間の短い新しいプロセスが到着するまで続行され、最速で終了するプロセスが常に優先されるようになります。
SJF アルゴリズムの例:
シナリオ 1: 到着時間が同じプロセス
例: 3 つのプロセスの到着時間とバースト時間を示す次の表を検討してください。 P1、P2、P3 。
| プロセス | バーストタイム | 到着時間 |
|---|---|---|
| P1 | 6ミリ秒 | 0ミリ秒 |
| P2 | 8ミリ秒 | 0ミリ秒 |
| P3 | 5ミリ秒 | 0ミリ秒 |
ステップバイステップの実行:
- 時間 0-5 (P3) : P3 は残り時間が最も短いため、5 ミリ秒間実行されます (合計残り時間: 0 ミリ秒)。
- タイム 5-11 (P1) : P1 は残り時間が最も短いため、6 ミリ秒間実行されます (残りの合計時間: 0 ミリ秒)。
- タイム 11-19 (P2) : P2 は残り時間が最も短いため、8 ミリ秒間実行されます (残りの合計時間: 0 ミリ秒)。
ガントチャート:
C++のベクトルのサイズ
では平均値を計算してみましょう 待ち時間と折り返し 時間:
私たちが知っているように
- 所要時間 = 完了時間 - 到着時間
- 待ち時間 = ターンアラウンドタイム - バーストタイム
| プロセス | 到着時間 (で) | バーストタイム (BT) | 完了時間(CT) | 所要時間(TAT) | 待ち時間 (WT) |
|---|---|---|---|---|---|
| P1 | 私のモニター画面の大きさはどれくらいですか | 6 | 11 | 11-0 = 11 | 11-6 = 5 |
| P2 | 8 スイッチメソッドJava | 19 | 19-0 = 19 | 19-8 = 11 | |
| P3 | 5 | 5 | 5-0 = 5 | 5-5 = 0 |
今
- 平均所要時間 = (11 + 19 + 5)/3 = 11.6 ミリ秒
- 平均待ち時間 = (5 + 0 + 11 )/3 = 16/3 = 5.33 ミリ秒
シナリオ 2: 到着時間が異なるプロセス
3 つのプロセス P1、P2、および P3 の到着時間とバースト時間を示す次の表を考えてみましょう。
| プロセス | バーストタイム | 到着時間 |
|---|---|---|
| P1 | 6ミリ秒 | 0ミリ秒 |
| P2 | 3ミリ秒 | 1ミリ秒 |
| P3 | 7ミリ秒 | 2ミリ秒 |
ステップバイステップの実行:
- 時間 0-1 (P1) : P1 は残り時間が最も短いため、1 ミリ秒間実行されます (残りの合計時間: 5 ミリ秒)。
- 時間 1-4 (P2) : P2 は、P1 と P2 の中で残り時間が最も短いため、3 ミリ秒間実行されます (合計残り時間: 0 ミリ秒)。
- タイム 4-9 (P1) : P1 は、P1 と P3 の中で残り時間が最も短いため、5 ミリ秒間実行されます (合計残り時間: 0 ミリ秒)。
- 時間 9-16 (P3) : P3 は残り時間が最も短いため、7 ミリ秒間実行されます (残りの合計時間: 0 ミリ秒)。
ガントチャート:
jQueryとは何ですか
では平均値を計算してみましょう 待ち時間と折り返し 時間:
| プロセス | 到着時刻(AT) | バーストタイム(BT) | 完了時間(CT) | 所要時間(TAT) | 待ち時間 (WT) |
|---|---|---|---|---|---|
| P1 | 6 | 9 | 9-0 = 9 | 9-6 = 3 | |
| P2 | 1 Java文字列比較 | 3 | 4 | 4-1 = 3 | 3-3 = 0 |
| P3 | 2 | 7 | 16 | 16-2 = 14 | 14-7 = 7 |
- 平均所要時間 = (9 + 14 + 3)/3 = 8.6 ミリ秒
- 平均待ち時間 = (3 + 0 + 7 )/3 = 10/3 = 3.33 ミリ秒
SRTFアルゴリズムの実装
ステップ 1: 到着時間とバースト時間を含むプロセス数を入力します。
ステップ 2: 残り時間 (バースト時間) 現在時刻 = 0 とカウンターを初期化します。
ステップ 3: 時間単位ごとに、到着したプロセスを準備完了キューに追加します。
ステップ 4: 残り時間が最も短いプロセスを選択します (短いプロセスが到着した場合はプリエンプトされます)。
ステップ5: 選択したプロセスを 1 ユニットに対して実行し、その残り時間を減らし、現在の時間を増やします。
ステップ6: プロセスが完了すると、次のようになります。
- 所要時間 = 完了時間 − 到着時間
- 待ち時間 = ターンアラウンドタイム − バーストタイム
ステップ 7: すべてのプロセスが完了するまで、手順 3 ~ 6 を繰り返します。
ステップ8: 平均待ち時間と所要時間を計算します。
ステップ9: 各プロセスの完了待ち時間とターンアラウンド時間を平均とともに表示します。
コードの実装
残り時間最短優先を実現するプログラムは以下の通りです。
C++#include #include #include using namespace std; struct Process { int id arrivalTime burstTime remainingTime waitingTime turnaroundTime completionTime; }; int main() { int n currentTime = 0 completed = 0; cout << 'Enter number of processes: '; cin >> n; vector<Process> p(n); for (int i = 0; i < n; i++) { p[i].id = i + 1; cin >> p[i].arrivalTime >> p[i].burstTime; p[i].remainingTime = p[i].burstTime; } while (completed < n) { int idx = -1; for (int i = 0; i < n; i++) { if (p[i].arrivalTime <= currentTime && p[i].remainingTime > 0 && (idx == -1 || p[i].remainingTime < p[idx].remainingTime)) { idx = i; } } if (idx != -1) { p[idx].remainingTime--; currentTime++; if (p[idx].remainingTime == 0) { p[idx].completionTime = currentTime; p[idx].turnaroundTime = currentTime - p[idx].arrivalTime; p[idx].waitingTime = p[idx].turnaroundTime - p[idx].burstTime; completed++; } } else { currentTime++; } } double totalWT = 0 totalTAT = 0; for (auto &proc : p) { totalWT += proc.waitingTime; totalTAT += proc.turnaroundTime; cout << 'P' << proc.id << ' CT: ' << proc.completionTime << ' WT: ' << proc.waitingTime << ' TAT: ' << proc.turnaroundTime << endl; } cout << 'Avg WT: ' << totalWT / n << ' Avg TAT: ' << totalTAT / n << endl; }
Java import java.util.*; class Process { int id arrivalTime burstTime remainingTime waitingTime turnaroundTime completionTime; public Process(int id int arrivalTime int burstTime) { this.id = id; this.arrivalTime = arrivalTime; this.burstTime = burstTime; this.remainingTime = burstTime; } } public class SRTF { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); Process[] processes = new Process[n]; for (int i = 0; i < n; i++) { int arrivalTime = sc.nextInt() burstTime = sc.nextInt(); processes[i] = new Process(i + 1 arrivalTime burstTime); } Arrays.sort(processes Comparator.comparingInt(p -> p.arrivalTime)); int currentTime = 0 completed = 0; while (completed < n) { int idx = -1; for (int i = 0; i < n; i++) { if (processes[i].arrivalTime <= currentTime && processes[i].remainingTime > 0 && (idx == -1 || processes[i].remainingTime < processes[idx].remainingTime)) { idx = i; } } if (idx != -1) { processes[idx].remainingTime--; currentTime++; if (processes[idx].remainingTime == 0) { processes[idx].completionTime = currentTime; processes[idx].turnaroundTime = currentTime - processes[idx].arrivalTime; processes[idx].waitingTime = processes[idx].turnaroundTime - processes[idx].burstTime; completed++; } } else { currentTime++; } } double totalWT = 0 totalTAT = 0; for (Process p : processes) { totalWT += p.waitingTime; totalTAT += p.turnaroundTime; System.out.println('P' + p.id + ' CT: ' + p.completionTime + ' WT: ' + p.waitingTime + ' TAT: ' + p.turnaroundTime); } System.out.println('Avg WT: ' + totalWT / n + ' Avg TAT: ' + totalTAT / n); } }
Python class Process: def __init__(self id arrival_time burst_time): self.id = id self.arrival_time = arrival_time self.burst_time = burst_time self.remaining_time = burst_time def srtf(processes): current_time completed = 0 0 while completed < len(processes): idx = -1 for i p in enumerate(processes): if p.arrival_time <= current_time and p.remaining_time > 0 and (idx == -1 or p.remaining_time < processes[idx].remaining_time): idx = i if idx != -1: processes[idx].remaining_time -= 1 current_time += 1 if processes[idx].remaining_time == 0: processes[idx].completion_time = current_time processes[idx].turnaround_time = current_time - processes[idx].arrival_time processes[idx].waiting_time = processes[idx].turnaround_time - processes[idx].burst_time completed += 1 else: current_time += 1 def print_results(processes): total_wt total_tat = 0 0 for p in processes: total_wt += p.waiting_time total_tat += p.turnaround_time print(f'P{p.id} CT: {p.completion_time} WT: {p.waiting_time} TAT: {p.turnaround_time}') print(f'Avg WT: {total_wt / len(processes)} Avg TAT: {total_tat / len(processes)}') n = int(input('Enter number of processes: ')) processes = [Process(i + 1 *map(int input(f'Enter arrival and burst time for P{i + 1}: ').split())) for i in range(n)] srtf(processes) print_results(processes)
出力
Enter number of processes: Avg WT: -nan Avg TAT: -nan
SRTFの利点 スケジュール設定
- 平均待ち時間を最小限に抑える : SRTF は、残りの実行時間が最も短いプロセスを優先することにより、平均待機時間を短縮します。
- 短いプロセスで効率的 : プロセスが短いほど早く完了し、システム全体の応答性が向上します。
- タイムクリティカルなシステムに最適 : 時間に敏感なプロセスが迅速に実行されるようにします。
SRTFの欠点 スケジュール設定
- 長いプロセスの枯渇 : 短いプロセスが到着し続けると、長いプロセスが無期限に遅延する可能性があります。
- バースト時間の予測が困難 : プロセスのバースト時間を正確に予測することは困難であり、スケジューリングの決定に影響を与えます。
- 高いオーバーヘッド : コンテキストの切り替えが頻繁に行われると、オーバーヘッドが増加し、システムのパフォーマンスが低下する可能性があります。
- リアルタイム システムには適さない : リアルタイム タスクは、頻繁なプリエンプションにより遅延が発生する可能性があります。