Shortest Remaining Time First (Preemptive SJF) Scheduling Algorithm (original) (raw)

Last Updated : 03 Feb, 2025

Try it on GfG Practice redirect icon

In this post, we will talk about the pre-emptive version of Shortest Job First (SJF) scheduling, called **Shortest Remaining Time First (SRTF). In SRTF, the process with the least time left to finish is selected to run. The running process will continue until it finishes or a new process with a shorter remaining time arrives. This way, the process that can finish the fastest is always given priority.

**Implementation of SRTF Algorithm

**Steps:

**1. Input Process Details

2. Track Remaining Time

3. Initialize Variables

4. Check for Arriving Processes

5. Select Shortest Remaining Time

6. Execute Process

7. Process Completion

8. Repeat Until All Complete

9. Calculate Averages

10. Output Results

**Advantages of SRTF Scheduling

  1. **Minimizes Average Waiting Time: SRTF reduces the average waiting time by prioritizing processes with the shortest remaining execution time.
  2. **Efficient for Short Processes: Shorter processes get completed faster, improving overall system responsiveness.
  3. **Ideal for Time-Critical Systems: It ensures that time-sensitive processes are executed quickly.

**Disadvantages of SRTF Scheduling

  1. **Starvation of Long Processes: Longer processes may be delayed indefinitely if shorter processes keep arriving.
  2. **Difficult to Predict Burst Times: Accurate prediction of process burst times is challenging and affects scheduling decisions.
  3. **High Overhead: Frequent context switching can increase overhead and slow down system performance.
  4. **Not Suitable for Real-Time Systems: Real-time tasks may suffer delays due to frequent preemptions.

**Examples to show working of Pre-emptive Shortest Job First CPU Scheduling Algorithm

Scenario 1: Processes with Same Arrival Time

**Example: Consider the following table of arrival time and burst time for three processes **P1, P2 and P3.

**Process **Burst Time **Arrival Time
P1 6 ms 0 ms
P2 8 ms 0 ms
P3 5 ms 0 ms

**Step-by-Step Execution:

  1. **Time 0-5 (P3): P3 runs for 5 ms (total time left: 0 ms) as it has shortest remaining time left.
  2. **Time 5-11 (P1): P1 runs for 6 ms (total time left: 0 ms) as it has shortest remaining time left.
  3. **Time 11-19 (P2): P2 runs for 8 ms (total time left: 0 ms) as it has shortest remaining time left.

**Gantt chart :

Now, lets calculate average waiting time and turn around time:

As we know,

Process Arrival Time(AT) Burst Time(BT) Completion Time (CT) Turn Around Time (TAT) Waiting Time (WT)
P1 0 6 11 11-0 = 11 11-6 = 5
P2 0 8 19 19-0 = 19 19-8 = 11
P3 0 5 5 5-0 = 5 5-5 = 0

Now,

Scenario 2: Processes with Different Arrival Times

Consider the following table of arrival time and burst time for three processes P1, P2 and P3.

**Process **Burst Time **Arrival Time
P1 6 ms 0 ms
P2 3 ms 1 ms
P3 7 ms 2 ms

**Step-by-Step Execution:

  1. **Time 0-1 (P1): P1 runs for 1 ms (total time left: 5 ms) as it has shortest remaining time left.
  2. **Time 1-4 (P2): P2 runs for 3 ms (total time left: 0 ms) as it has shortest remaining time left among P1 and P2.
  3. **Time 4-9 (P1): P1 runs for 5 ms (total time left: 0 ms) as it has shortest remaining time left among P1 and P3.
  4. **Time 9-16 (P3): P3 runs for 7 ms (total time left: 0 ms) as it has shortest remaining time left.

**Gantt chart :

Now, lets calculate average waiting time and turn around time:

Process Arrival Time (AT) Burst Time (BT) Completion Time (CT) Turn Around Time (TAT) Waiting Time (WT)
P1 0 6 9 9-0 = 9 9-6 = 3
P2 1 3 4 4-1 = 3 3-3 = 0
P3 2 7 16 16-2 = 14 14-7 = 7

Code Implementation

Program to implement Shortest Remaining Time First is as follows:

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 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)

`

Output

Enter number of processes: Avg WT: -nan Avg TAT: -nan