Shortest Remaining Time First (SRTF) With predicted Time
Last Updated :
15 May, 2024
CPU scheduling algorithms are essential components of operating systems that determine the order in which processes are executed on a computer's central processing unit (CPU). These algorithms aim to optimize CPU utilization, reduce waiting times, and enhance system performance by efficiently managing the execution of tasks in a multi-tasking environment. Various algorithms, such as First-Come, First-Served (FCFS), Shortest Job Next (SJN), Round Robin (RR), and Priority Scheduling, are employed to achieve these objectives, each with its own set of advantages and limitations. In this article, we study about Shortest Remaining Time First CPU Scheduling algorithm.
What is the SRTF Algorithm?
Shortest Remaining Time First (SRTF) is the preemptive version of the Shortest Job Next (SJN) algorithm, where the processor is allocated to the job closest to completion. It is also known as Shortest Job First with dynamic priority. It is a CPU scheduling algorithm of the Operating System.
In SRTF with predicted time, each process is assigned a priority based on its expected remaining burst time. The process with the highest priority (i.e., the shortest predicted remaining burst time) is selected to execute next. The predicted burst time is updated dynamically as the process runs, and the priority is recalculated based on the edited expected burst time.
Advantages of SRTF
The advantage of SRTF with predicted time is that:
- It can reduce the number of preemptions and context switches, as processes with shorter predicted burst times will be given higher priority.
- The accuracy of the predicted burst times can affect the performance of the algorithm, as inaccurate predictions can lead to poor scheduling decisions.
Disadvantages of SRTF
- Shortest Remaining Time First (SRTF) is a CPU scheduling algorithm in which the process with the smallest remaining burst time is scheduled next.
- This algorithm can be impractical in certain scenarios, such as when the burst times of the processes are not known in advance or when there are frequent arrivals and departures of processes.
Pseudo Code
1. Initialize the ready queue with all the processes.
2. While the ready queue is not empty:
a. Find the process with the smallest predicted remaining burst time from the input.
b. Execute the process for a unit of time.
c. Update the predicted remaining burst time of the processes based on it's past execution history.
d. If the process has completed its execution, remove it from the ready queue.
e. If a new process arrives, add it to the ready queue.
C Program
C
#include <stdio.h>
#include <stdbool.h>
#define MAX_PROCESSES 100
//declaring the stucture
struct process {
int pid;
int arrival_time;
int burst_time;
int remaining_time;
};
int main() {
int n;
struct process processes[MAX_PROCESSES];
bool completed[MAX_PROCESSES] = {false};
int current_time = 0;
int shortest_time = 0;
int shortest_index = 0;
printf("Enter the number of processes: ");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
printf("Enter arrival time and burst time for process %d: ", i+1);
scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);
processes[i].pid = i+1;
processes[i].remaining_time = processes[i].burst_time;
}
printf("\n");
while (true) {
bool completed_all = true;
for (int i = 0; i < n; i++) {
if (!completed[i]) {
int all_completed = false;
if (processes[i].arrival_time <= current_time &&
processes[i].remaining_time < processes[shortest_index].remaining_time) {
shortest_index = i;
}
}
}
if (completed_all) {
break;
}
if (shortest_index != -1) {
processes[shortest_index].remaining_time--;
if (processes[shortest_index].remaining_time == 0) {
completed[shortest_index] = true;
}
}
current_time++;
shortest_index = -1;
}
printf("Process\tArrival Time\tBurst Time\tWaiting Time\tTurnAround Time\n");
int total_waiting_time = 0;
int total_turnaround_time = 0;
for (int i = 0; i < n; i++) {
int waiting_time = 0;
int turnaround_time = 0;
waiting_time = current_time - processes[i].burst_time - processes[i].arrival_time;
turnaround_time = current_time - processes[i].arrival_time;
total_waiting_time += waiting_time;
total_turnaround_time += turnaround_time;
printf("%d\t%d\t\t%d\t\t%d\t\t%d\n", processes[i].pid, processes[i].arrival_time, processes[i].burst_time, waiting_time, turnaround_time);
}
float avg_waiting_time = (float) total_waiting_time / n;
float avg_turnaround_time = (float) total_turnaround_time / n;
printf("The Average Waiting Time: %.2f\n", avg_waiting_time);
printf("The Average Turnaround Time: %.2f\n", avg_turnaround_time);
return 0;
}
Output
Output_CC++ Code
C++
#include<bits/stdc++.h>
using namespace std;
struct process {
int pid, arrival_time, burst_time, remaining_time, predicted_time;
};
bool cmp(process a, process b) {
if (a.arrival_time == b.arrival_time) {
if (a.predicted_time == b.predicted_time) {
return a.pid < b.pid;
}
return a.predicted_time < b.predicted_time;
}
return a.arrival_time < b.arrival_time;
}
void SRTF(vector<process>& processes) {
int n = processes.size();
int current_time = 0, completed = 0;
vector<int> waiting_time(n, 0);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
while (completed < n) {
for (int i = 0; i < n; i++) {
if (processes[i].arrival_time <= current_time && processes[i].remaining_time > 0) {
pq.push(make_pair(processes[i].predicted_time, processes[i].pid));
}
}
if (pq.empty()) {
current_time++;
continue;
}
int pid = pq.top().second;
pq.pop();
processes[pid].remaining_time--;
current_time++;
if (processes[pid].remaining_time == 0) {
completed++;
waiting_time[pid] = current_time - processes[pid].arrival_time - processes[pid].burst_time;
}
else {
processes[pid].predicted_time = processes[pid].remaining_time + current_time;
}
}
cout << "PID\tArrival Time\tBurst Time\tWaiting Time\n";
int total_waiting_time = 0;
for (int i = 0; i < n; i++) {
cout << processes[i].pid << "\t" << processes[i].arrival_time << "\t\t" << processes[i].burst_time << "\t\t" << waiting_time[i] << "\n";
total_waiting_time += waiting_time[i];
}
cout << "Average waiting time = " << (float)total_waiting_time / n << "\n";
}
int main() {
int n;
cout << "Enter the number of processes: ";
cin >> n;
vector<process> processes(n);
for (int i = 0; i < n; i++) {
processes[i].pid = i;
cout << "Enter the arrival time and burst time of process " << i << ": ";
cin >> processes[i].arrival_time >> processes[i].burst_time;
processes[i].remaining_time = processes[i].burst_time;
processes[i].predicted_time = processes[i].burst_time;
}
sort(processes.begin(), processes.end(), cmp);
SRTF(processes);
return 0;
}
Output
Output_C++Java Code
Java
import java.util.*;
public class SRTF {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number of processes: ");
int n = sc.nextInt();
int[] processId = new int[n];
int[] arrivalTime = new int[n];
int[] burstTime = new int[n];
int[] remainingTime = new int[n];
int[] predictedTime = new int[n];
int[] completionTime = new int[n];
int[] turnaroundTime = new int[n];
int[] waitingTime = new int[n];
boolean[] isCompleted = new boolean[n];
int currentTime = 0;
int completed = 0;
for (int i = 0; i < n; i++) {
System.out.println("Enter details for process " + (i + 1));
System.out.print("Process ID: ");
processId[i] = sc.nextInt();
System.out.print("Arrival time: ");
arrivalTime[i] = sc.nextInt();
System.out.print("Burst time: ");
burstTime[i] = sc.nextInt();
remainingTime[i] = burstTime[i];
System.out.print("Predicted time: ");
predictedTime[i] = sc.nextInt();
}
while (completed!=n) {
int shortest=-1;
for (int i=0; i<n;i++) {
if (!isCompleted[i] && arrivalTime[i] <= currentTime) {
if (shortest == -1 || remainingTime[i] < remainingTime[shortest]) {
shortest=i;
}
}
}
if (shortest == -1) {
currentTime++;
continue;
}
remainingTime[shortest]--;
if (remainingTime[shortest] == 0) {
completionTime[shortest] = currentTime + 1;
turnaroundTime[shortest] = completionTime[shortest] - arrivalTime[shortest];
waitingTime[shortest] = turnaroundTime[shortest] - burstTime[shortest];
isCompleted[shortest] = true;
completed++;
}
currentTime++;
}
System.out.println("\nProcess\tArrival Time\tBurst Time\tPredicted Time\tCompletion Time\tTurnaround Time\tWaiting Time");
for (int i = 0; i < n; i++) {
System.out.println(processId[i] + "\t\t" + arrivalTime[i] + "\t\t" + burstTime[i] + "\t\t" + predictedTime[i] + "\t\t\t" + completionTime[i] + "\t\t\t" + turnaroundTime[i] + "\t\t\t" + waitingTime[i]);
}
double totalTurnaroundTime = 0;
double totalWaitingTime = 0;
for (int i = 0; i < n; i++) {
totalTurnaroundTime += turnaroundTime[i];
totalWaitingTime += waitingTime[i];
}
System.out.println("\nAverage Turnaround Time: " + (totalTurnaroundTime / n));
System.out.println("Average Waiting Time: " + (totalWaitingTime / n));
}
}
Output
Enter the number of processes: 3
Enter details for process 1
Process ID: 1
Arrival time: 0
Burst time: 3
Predicted time: 2
Enter details for process 2
Process ID: 3
Arrival time: 4
Burst time: 9
Predicted time: 6
Enter details for process 3
Process ID: 2
Arrival time: 4
Burst time: 10
Predicted time: 7
Process Arrival Time Burst Time Predicted Time Completion Time Turnaround Time Waiting Time
1 0 3 2 3 3 0
3 4 9 6 13 9 0
2 4 10 7 23 19 9
Average Turnaround Time: 10.333333333333334
Process ID: 4
Arrival time: 5
Burst time: 12
Predicted time: 9
Process Arrival Time Burst Time Predicted Time Completion Time Turnaround Time Waiting Time
1 0 5 4 5 5 0
2 3 9 6 14 11 2
3 4 10 7 24 20 10
4 5 12 9 36 31 19
Average Turnaround Time: 16.75
Average Waiting Time: 7.75
JavaScript Code
JavaScript
class Process {
constructor(id, arrivalTime, burstTime, predictedTime) {
this.id = id;
this.arrivalTime = arrivalTime;
this.burstTime = burstTime;
this.predictedTime = predictedTime;
this.remainingTime = burstTime;
}
}
function SRTF(processes) {
let currentTime = 0;
let completedProcesses = [];
let readyQueue = [];
let runningProcess = null;
while (completedProcesses.length < processes.length) {
// Check if there are any processes that have arrived
for (let i = 0; i < processes.length; i++) {
if (processes[i].arrivalTime <= currentTime && !completedProcesses.includes(processes[i])) {
readyQueue.push(processes[i]);
}
}
// Sort readyQueue by remaining time
readyQueue.sort((a, b) => {
if (a.remainingTime === b.remainingTime) {
return a.predictedTime - b.predictedTime;
}
return a.remainingTime - b.remainingTime;
});
// If runningProcess has completed, add it to completedProcesses and set runningProcess to null
if (runningProcess && runningProcess.remainingTime === 0) {
completedProcesses.push(runningProcess);
runningProcess = null;
}
// If there are processes in the readyQueue, start the one with the shortest remaining time
if (readyQueue.length > 0) {
const shortestProcess = readyQueue.shift();
if (runningProcess !== shortestProcess) {
runningProcess = shortestProcess;
}
}
// Decrement remaining time of runningProcess and increment currentTime
if (runningProcess) {
runningProcess.remainingTime--;
currentTime++;
} else {
currentTime++;
}
}
return completedProcesses;
}
// Example usage
const processes = [
new Process(1, 0, 6, 4),
new Process(2, 2, 4, 2),
new Process(3, 4, 2, 1),
new Process(4, 5, 3, 3)
];
const completedProcesses = SRTF(processes);
console.log(completedProcesses);
Output
[
Process {
id: 3,
arrivalTime: 4,
burstTime: 2,
predictedTime: 1,
remainingTime: -1
},
Process {
id: 2,
arrivalTime: 2,
burstTime: 4,
predictedTime: 2,
remainingTime: -4
},
Process {
id: 4,
arrivalTime: 5,
burstTime: 3,
predictedTime: 3,
remainingTime: -9
},
Process {
id: 1,
arrivalTime: 0,
burstTime: 6,
predictedTime: 4,
remainingTime: -1
}
]
Conclusion
In conclusion, SRTF is a CPU scheduling algorithm that prioritizes tasks based on their remaining execution time. It is an extension of the SJF algorithm and can reduce the average waiting time for all tasks. However, it requires knowledge of the remaining execution time of each task, which may not always be available, and the predicted execution times can be used as a solution for the program.
Similar Reads
Shortest Job First CPU Scheduling with Predicted Burst Time
Shortest Job First (SJF) is an optimal scheduling algorithm as it gives maximum Throughput and minimum average waiting time (WT) and turnaround time (TAT) but it is not practically implementable because the burst time of a process can't be predicted in advance. We may not know the length of the next
5 min read
Introduction of Shortest Remaining Time First (SRTF) algorithm
Shortest Remaining Time First (SRTF) is the preemptive version of Shortest Job Next (SJN) algorithm, where the processor is allocated to the job closest to completion. This algorithm requires advanced concept and knowledge of CPU time required to process the job in an interactive system, and hence c
2 min read
Shortest Remaining Time First (Preemptive SJF) Scheduling Algorithm
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 shorte
8 min read
SSTF Full Form - Shortest Seek Time First
SSTF (Shortest Seek Time First) is an abbreviation that selects the request which is closest to the current head position before moving the head away to service other requests. This is done by selecting the request which has the least seek time from the current head position. SSTFSSTF scheduling pri
3 min read
LRTF Scheduling Full Form - Longest Remaining Time First
LRTF stands for Longest Remaining Time First. In the LRTF scheduling algorithm, the job that has the highest burst time is allocated CPU first. We keep monitoring the burst times periodically and assign the then highest burst time process to the CPU. It is a preemptive mode of the Longest Job First
2 min read
Shortest Job First or SJF CPU Scheduling
Shortest Job First (SJF) or Shortest Job Next (SJN) is a scheduling process that selects the waiting process with the smallest execution time to execute next. This scheduling method may or may not be preemptive. Significantly reduces the average waiting time for other processes waiting to be execute
4 min read
Shortest Job Next (SJN) in Operating System
In Shortest Job Next(SJN), when choosing the next job to run, look at all the processes in the ready state and dispatch the one with the smallest service time. In this case, we need to know the service times at any given point in time. It is a non-preemptive algorithm. A new job will not be given a
6 min read
Timing Constraints in Real-time System
Timing constraints is a vital attribute in real-time systems. Timing constraints decides the total correctness of the result in real-time systems. The correctness of results in real-time system does not depends only on logical correctness but also the result should be obtained within the time constr
3 min read
Longest Remaining Time First (LRTF) CPU Scheduling Program
We have given some processes with arrival time and Burst Time and we have to find the completion time (CT), Turn Around Time(TAT), Average Turn Around Time (Avg TAT), Waiting Time(WT), Average Waiting Time (AWT) for the given processes. Prerequisite: CPU Scheduling | Longest Remaining Time First (LR
15+ min read
Shortest Job First (or SJF) CPU Scheduling Non-preemptive algorithm using Segment Tree
Shortest job first (SJF) or shortest job next, is a scheduling policy that selects the waiting process with the smallest execution time to execute next. SJN is a non-preemptive algorithm.  Shortest Job first has the advantage of having a minimum average waiting time among all scheduling algorithms.
15+ min read