CPU scheduling is the process of deciding which process will own the CPU to use while another process is suspended. The main function of CPU scheduling is to ensure that whenever the CPU remains idle, the OS has at least selected one of the processes available in the ready-to-use line. Highest Response Ratio Next (HRRN) Scheduling is a part of nonpreemptive CPU scheduling.
What is the Highest Response Ratio Next (HRRN) Scheduling?
One of the most optimal scheduling algorithms is the Highest Response Ratio Next (HRNN). This algorithm is a non-preemptive algorithm in which, HRRN scheduling is done based on an extra parameter, which is called Response Ratio. Given N processes with their Arrival times and Burst times, the task is to find the average waiting time and an average turnaround time using the HRRN scheduling algorithm.Â
The name itself states that we need to find the response ratio of all available processes and select the one with the highest Response Ratio. A process once selected will run till completion. below is the formula to calculate the Response Ratio.
Response Ratio = (W + S)/S
Here, W is the waiting time of the process so far and S is the Burst time of the process.
Characteristics of HRRN Scheduling
- Highest Response Ratio Next is a non-preemptive CPU Scheduling algorithm and it is considered as one of the most optimal scheduling algorithms.
- The criteria for HRRN is Response Ratio, and the mode is Non-Preemptive.Â
- HRRN is considered as the modification of the Shortest Job First to reduce the problem of starvation.
- In comparison with SJF, during the HRRN scheduling algorithm, the CPU is allotted to the next process which has the highest response ratio, and not to the process having less burst time.
Performance of HRRN Scheduling
- Shorter Processes are favored.
- Aging without service increases the ratio, longer jobs can get past shorter jobs.
Examples of  Highest Response Ratio Next (HRRN) Scheduling
Example-1: Consider the following table of arrival time and burst time for four processes P1, P2, P3, P4Â and P5. Â
P1 Â |
0ms |
3ms |
P2 Â Â Â Â Â Â |
2ms |
6ms |
P3Â |
4ms |
4ms |
P4 Â Â Â |
6ms |
5ms |
P5 |
8ms |
2ms |
The Highest Response Ratio Next CPU Scheduling Algorithm will work on the basis of steps as mentioned below:
At time= 0,
- Available Processes: P1, Hence P1 starts executing till its completion.
0-2ms |
P1 |
0ms |
 |
P1 |
2ms |
3ms |
1ms |
At time = 2,
- Available Processes: P1, P2
- But P1 keep executing as HRRN is a non-preemptive algorithm and thus it will finish its execution
2-3ms |
P1 |
0ms |
P2 |
P1 |
1ms |
1ms |
0ms |
P2 |
2ms |
0ms |
6ms |
6ms |
At time = 3,
- Process P1 finish its execution
- Process P2 starts executing as it is only process available.
3-4ms |
P2 |
2ms |
 |
P2 |
1ms |
6ms |
5ms |
At time = 4,
- Process P3 arrives and wait for process P2 to execute
- Process P2 continue its execution
4-6ms |
P2 |
2ms |
P3 |
P2 |
2ms |
5ms |
3ms |
P3 |
4ms |
0ms |
4ms |
4ms |
At time = 6,
- Process P4 arrives and wait for the process P2 to execute
6-8ms |
P2 |
2ms |
P3, P4 |
P2 |
2ms |
3ms |
1ms |
P3 |
4ms |
0ms |
4ms |
4ms |
P4 |
6ms |
0ms |
5ms |
5ms |
At time = 8,
- Process P5 arrives and wait for its execution in the ready queue
8-9ms |
P2 |
2ms |
P3, P4, P5 |
P2 |
1ms |
1ms |
0ms |
P3 |
4ms |
0ms |
4ms |
4ms |
P4 |
6ms |
0ms |
5ms |
5ms |
P5 |
8ms |
0ms |
2ms |
2ms |
At time = 9,
- Process P2 completes its executionÂ
- Now there are 3 processes available, P3, P4 and P5. Since, P3, P4, P5 were available after 4, 6 and 8 units respectively.
- Therefore, waiting time for P3, P4 and P5 are (9 – 4 =)5, (9 – 6 =)3, and (9 – 8 =)1 unit respectively.
- Using the formula given above, Â (Response Ratio = (W + S)/S) calculate the Response Ratios of P3, P4 and P5 respectively as 2.25, 1.6 and 1.5.
- Clearly, P3 has the highest Response Ratio and so it gets scheduled
9-13ms |
P3 |
4ms |
P4, P5 |
P3 |
4ms |
4ms |
0ms |
P4 |
6ms |
0ms |
5ms |
5ms |
P5 |
8ms |
0ms |
2ms |
2ms |
At time = 13,
- Available Processes: P4 and P5
- Response Ratios of P4 and P5 are 2.4 and 3.5 respectively using the above formula.
- Clearly, P5 has the highest Response Ratio and so it gets scheduled
13-15ms |
P4 |
6ms |
P4 |
P5 |
0ms |
5ms |
5ms |
P5 |
8ms |
2ms |
2ms |
0ms |
At time = 15,
- After completion of process P5, Process P4 is selected at last and execute till it gets finished
15-20ms |
P4 |
6ms |
 |
P4 |
5ms |
5ms |
0ms |
At time = 20,
- Process P4 will finish its execution.
- The overall execution of the processes will be as shown below:
0-2ms |
P1 |
0ms |
 |
P1 |
2ms |
3ms |
1ms |
2-3ms |
P1 |
0ms |
P2 |
P1 |
1ms |
1ms |
0ms |
P2 |
2ms |
0ms |
6ms |
6ms |
3-4ms |
P2 |
2ms |
 |
P2 |
1ms |
6ms |
5ms |
4-6ms |
P2 |
2ms |
P3 |
P2 |
2ms |
5ms |
3ms |
P3 |
4ms |
0ms |
4ms |
4ms |
6-8ms |
P2 |
2ms |
P3, P4 |
P2 |
2ms |
3ms |
1ms |
P3 |
4ms |
0ms |
4ms |
4ms |
P4 |
6ms |
0ms |
5ms |
5ms |
8-9ms |
P2 |
2ms |
P3, P4, P5 |
P2 |
1ms |
1ms |
0ms |
P3 |
4ms |
0ms |
4ms |
4ms |
P4 |
6ms |
0ms |
5ms |
5ms |
P5 |
8ms |
0ms |
2ms |
2ms |
9-13ms |
P3 |
4ms |
P4, P5 |
P3 |
4ms |
4ms |
0ms |
P4 |
6ms |
0ms |
5ms |
5ms |
P5 |
8ms |
0ms |
2ms |
2ms |
13-15ms |
P4 |
6ms |
P4 |
P5 |
0ms |
5ms |
5ms |
P5 |
8ms |
2ms |
2ms |
0ms |
15-20ms |
P4 |
6ms |
 |
P4 |
5ms |
5ms |
0ms |
Gantt Chart –Â

Since, completion time (C.T) can be directly determined by Gantt chart, and Â
Turn Around Time (TAT)
= (Completion Time) – (Arrival Time)
Also, Waiting Time (WT)
= (Turn Around Time) – (Burst Time)Â
Therefore, final table look like, Â
P1 |
0 |
3 |
3 |
3-0 = 3 |
3-3 = 0 |
P2 |
2 |
6 |
9 |
9-2 = 7 |
7-6 = 1 |
P3 |
4 |
4 |
13 |
13-4 = 9 |
9-4 = 5 |
P4 |
6 |
5 |
20 |
20-6 = 14 |
14-5 = 9 |
P5 |
8 |
2 |
15 |
15-8 = 7 |
7-2 = 5 |
Output:Â Â
Total Turn Around Time = 40 ms
So, Average Turn Around Time = 40/5 = 8.00 ms
And, Total Waiting Time = 20 ms
So, Average Waiting Time = 20/5 = 4.00 msÂ
Implementation of HRRN Scheduling Â
- Input the number of processes, their arrival times and burst times.
- Sort them according to their arrival times.
- At any given time calculate the response ratios and select the appropriate process to be scheduled.
- Calculate the turn around time as completion time – arrival time.
- Calculate the waiting time as turn around time – burst time.
- Turn around time divided by the burst time gives the normalized turn around time.
- Sum up the waiting and turn around times of all processes and divide by the number of processes to get the average waiting and turn around time.
Below is the implementation of above approach:Â
C++
#include <bits/stdc++.h>
using namespace std;
struct process {
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
} p[10];
int n;
void sortByArrival()
{
struct process temp;
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (p[i].at > p[j].at) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
int main()
{
int i, j, sum_bt = 0;
char c;
float t, avgwt = 0, avgtt = 0;
n = 5;
int arriv[] = { 0, 2, 4, 6, 8 };
int burst[] = { 3, 6, 4, 5, 2 };
for (i = 0, c = 'A' ; i < n; i++, c++) {
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
p[i].completed = 0;
sum_bt += p[i].bt;
}
sortByArrival();
cout << "PN\tAT\tBT\tWT\tTAT\tNTT" ;
for (t = p[0].at; t < sum_bt;) {
float hrr = -9999;
float temp;
int loc;
for (i = 0; i < n; i++) {
if (p[i].at <= t && p[i].completed != 1) {
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
if (hrr < temp) {
hrr = temp;
loc = i;
}
}
}
t += p[loc].bt;
p[loc].wt = t - p[loc].at - p[loc].bt;
p[loc].tt = t - p[loc].at;
avgtt += p[loc].tt;
p[loc].ntt = (( float )p[loc].tt / p[loc].bt);
p[loc].completed = 1;
avgwt += p[loc].wt;
cout << "\n" << p[loc].name << "\t" << p[loc].at;
cout << "\t" << p[loc].bt << "\t" << p[loc].wt;
cout << "\t" << p[loc].tt << "\t" << p[loc].ntt;
}
cout << "\nAverage waiting time: " << avgwt / n << endl;
cout << "Average Turn Around time:" << avgtt / n;
}
|
C
#include <stdio.h>
struct process {
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
} p[10];
int n;
void sortByArrival()
{
struct process temp;
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (p[i].at > p[j].at) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
void main()
{
int i, j, t, sum_bt = 0;
char c;
float avgwt = 0, avgtt = 0;
n = 5;
int arriv[] = { 0, 2, 4, 6, 8 };
int burst[] = { 3, 6, 4, 5, 2 };
for (i = 0, c = 'A' ; i < n; i++, c++) {
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
p[i].completed = 0;
sum_bt += p[i].bt;
}
sortByArrival();
printf ( "\nName\tArrival Time\tBurst Time\tWaiting Time" );
printf ( "\tTurnAround Time\t Normalized TT" );
for (t = p[0].at; t < sum_bt;) {
float hrr = -9999;
float temp;
int loc;
for (i = 0; i < n; i++) {
if (p[i].at <= t && p[i].completed != 1) {
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
if (hrr < temp) {
hrr = temp;
loc = i;
}
}
}
t += p[loc].bt;
p[loc].wt = t - p[loc].at - p[loc].bt;
p[loc].tt = t - p[loc].at;
avgtt += p[loc].tt;
p[loc].ntt = (( float )p[loc].tt / p[loc].bt);
p[loc].completed = 1;
avgwt += p[loc].wt;
printf ( "\n%c\t\t%d\t\t" , p[loc].name, p[loc].at);
printf ( "%d\t\t%d\t\t" , p[loc].bt, p[loc].wt);
printf ( "%d\t\t%f" , p[loc].tt, p[loc].ntt);
}
printf ( "\nAverage waiting time:%f\n" , avgwt / n);
printf ( "Average Turn Around time:%f\n" , avgtt / n);
}
|
Java
import java.util.Arrays;
class Process {
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
}
public class HRRN {
static void sortByArrival(Process p[], int n)
{
Process temp;
int i, j;
for (i = 0 ; i < n - 1 ; i++) {
for (j = i + 1 ; j < n; j++) {
if (p[i].at > p[j].at) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
public static void main(String[] args)
{
int i, j, sum_bt = 0 ;
char c;
float t, avgwt = 0 , avgtt = 0 ;
int n = 5 ;
int arriv[] = { 0 , 2 , 4 , 6 , 8 };
int burst[] = { 3 , 6 , 4 , 5 , 2 };
Process[] p = new Process[n];
for (i = 0 , c = 'A' ; i < n; i++, c++) {
p[i] = new Process();
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
p[i].completed = 0 ;
sum_bt += p[i].bt;
}
sortByArrival(p, n);
System.out.println( "PN\tAT\tBT\tWT\tTAT\tNTT" );
for (t = p[ 0 ].at; t < sum_bt;) {
float hrr = - 9999 ;
float temp;
int loc = - 1 ;
for (i = 0 ; i < n; i++) {
if (p[i].at <= t && p[i].completed != 1 ) {
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
if (hrr < temp) {
hrr = temp;
loc = i;
}
}
}
t += p[loc].bt;
p[loc].wt = ( int )(t - p[loc].at - p[loc].bt);
p[loc].tt = ( int )(t - p[loc].at);
avgtt += p[loc].tt;
p[loc].ntt = (( float )p[loc].tt / p[loc].bt);
p[loc].completed = 1 ;
avgwt += p[loc].wt;
System.out.println(p[loc].name + "\t" + p[loc].at + "\t" + p[loc].bt
+ "\t" + p[loc].wt + "\t" + p[loc].tt
+ "\t" + p[loc].ntt);
}
System.out.println( "Average waiting time: " + (avgwt / n));
System.out.println( "Average Turn Around time:" + (avgtt / n));
}
}
|
Python3
def sortByArrival(at, n):
for i in range ( 0 , n - 1 ):
for j in range (i + 1 , n):
if at[i] > at[j]:
at[i], at[j] = at[j], at[i]
if __name__ = = '__main__' :
sum_bt = 0
avgwt = 0
avgTT = 0
n = 5
completed = [ 0 ] * n
waiting_time = [ 0 ] * n
turnaround_time = [ 0 ] * n
normalised_TT = [ 0 ] * n
arrival_time = [ 0 , 2 , 4 , 6 , 8 ]
burst_time = [ 3 , 6 , 4 , 5 , 2 ]
process = []
for i in range ( 0 , n):
process.append( chr ( 65 + i))
sum_bt + = burst_time[i]
sortByArrival(arrival_time, n)
print ( "Name" , "Arrival time" ,
"Burst time" , "Waiting Time" ,
"Turnaround " , "Normalized TT" )
t = arrival_time[ 0 ]
while (t < sum_bt):
hrr = - 9999
temp, loc = 0 , 0
for i in range ( 0 , n):
if arrival_time[i] < = t and completed[i] ! = 1 :
temp = ((burst_time[i] +
(t - arrival_time[i])) /
burst_time[i])
if hrr < temp:
hrr = temp
loc = i
t + = burst_time[loc]
waiting_time[loc] = (t - arrival_time[loc] -
burst_time[loc])
turnaround_time[loc] = t - arrival_time[loc]
avgTT + = turnaround_time[loc]
normalised_TT = float (turnaround_time[loc] /
burst_time[loc])
completed[loc] = 1
avgwt + = waiting_time[loc]
print (process[loc], "\t\t" , arrival_time[loc],
"\t\t" , burst_time[loc], "\t\t" ,
waiting_time[loc], "\t\t" ,
turnaround_time[loc], "\t\t" ,
"{0:.6f}" . format (normalised_TT))
print ( "Average waiting time: {0:.6f}" . format (avgwt / n))
print ( "Average Turn Around time: {0:.6f}" . format (avgTT / n))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class Process {
public char name;
public int at, bt, ct, wt, tt;
public int completed;
public float ntt;
}
class HelloWorld {
public static void sortByArrival(Process[] p, int n)
{
Process temp;
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (p[i].at > p[j].at) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
static void Main() {
int i, j, sum_bt = 0;
char c;
float t, avgwt = 0, avgtt = 0;
int n = 5;
int [] arriv = { 0, 2, 4, 6, 8 };
int [] burst = { 3, 6, 4, 5, 2 };
Process[] p = new Process[n];
for (i = 0, c = 'A' ; i < n; i++, c++) {
p[i] = new Process();
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
p[i].completed = 0;
sum_bt += p[i].bt;
}
sortByArrival(p, n);
Console.WriteLine( "PN\tAT\tBT\tWT\tTAT\tNTT" );
for (t = p[0].at; t < sum_bt;) {
float hrr = -9999;
float temp;
int loc = -1;
for (i = 0; i < n; i++) {
if (p[i].at <= t && p[i].completed != 1) {
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
if (hrr < temp) {
hrr = temp;
loc = i;
}
}
}
t += p[loc].bt;
p[loc].wt = ( int )(t - p[loc].at - p[loc].bt);
p[loc].tt = ( int )(t - p[loc].at);
avgtt += p[loc].tt;
p[loc].ntt = (( float )p[loc].tt / p[loc].bt);
p[loc].completed = 1;
avgwt += p[loc].wt;
Console.WriteLine(p[loc].name + "\t" + p[loc].at + "\t" + p[loc].bt
+ "\t" + p[loc].wt + "\t" + p[loc].tt
+ "\t" + p[loc].ntt);
}
Console.WriteLine( "Average waiting time: " + (avgwt / n));
Console.WriteLine( "Average Turn Around time:" + (avgtt / n));
}
}
|
Javascript
class process {
constructor(){
this .name = '#' ;
this .at = 0;
this .bt = 0;
this .ct = 0;
this .wt = 0;
this .tt = 0;
this .completed= 0;
this .ntt = 0;
}
}
let p = new Array(10);
for (let i = 0; i < 10; i++){
p[i] = new process();
}
let n;
function sortByArrival()
{
let temp;
let i, j;
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (p[i].at > p[j].at) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
let i, j, sum_bt = 0;
let c;
let t, avgwt = 0, avgtt = 0;
n = 5;
let arriv = [0, 2, 4, 6, 8];
let burst = [3, 6, 4, 5, 2];
for (i = 0, c = 'A' ; i < n; i++) {
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
p[i].completed = 0;
sum_bt += p[i].bt;
c = String.fromCharCode(c.charCodeAt(0) + 1);
}
sortByArrival();
console.log( "PN\tAT\tBT\tWT\tTAT\tNTT" );
for (t = p[0].at; t < sum_bt;) {
let hrr = -9999;
let temp;
let loc;
for (i = 0; i < n; i++) {
if (p[i].at <= t && p[i].completed != 1) {
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
if (hrr < temp) {
hrr = temp;
loc = i;
}
}
}
t += p[loc].bt;
p[loc].wt = t - p[loc].at - p[loc].bt;
p[loc].tt = t - p[loc].at;
avgtt += p[loc].tt;
p[loc].ntt = (p[loc].tt / p[loc].bt);
p[loc].completed = 1;
avgwt += p[loc].wt;
console.log(p[loc].name + "\t" + p[loc].at + "\t" + p[loc].bt + "\t" + p[loc].wt + "\t" + p[loc].tt + "\t" + p[loc].ntt);
}
console.log( "\nAverage waiting time: " + avgwt / n);
console.log( "Average Turn Around time:" + avgtt / n);
|
Output
PN AT BT WT TAT NTT
A 0 3 0 3 1
B 2 6 1 7 1.16667
C 4 4 5 9 2.25
E 8 2 5 7 3.5
D 6 5 9 14 2.8
Average waiting time: 4
Average Turn Around time:8
Advantages of HRRN Scheduling
- HRRN Scheduling algorithm generally gives better performance than the shortest job first Scheduling.
- There is a reduction in waiting time for longer jobs and also it encourages shorter jobs.
- Using HRRN algorithm, the throughput increases.
Disadvantages of HRRN Scheduling
- The on ground implementation of HRRN scheduling is not possible as it is not possible know the burst time of every job in advance.
- In this scheduling, there may occur overload on the CPU.
FAQs on Highest Response Ratio Next (HRRN) Scheduling
Q.1: Is HRRN preemptive or non preemptive?
Answer:
The HRRN algorithm is non-preemptive in nature, and it bases scheduling decisions on an additional parameter known as response ratio. Every job that is open is assigned a response ratio, the job with the highest response ratio takes precedence over the others.
Q.2: What are the problems with HRRN?
Answer:
The following is the HRNN scheduling algorithm’s drawback:
- The inability to predict the peak period of each operation makes the practical application of HRRN scheduling unfeasible.
Q.3: How does HRRN scheduling work?
Answer:
basically, HRRN is thought of as a modification of Shortest Job First to lessen the problem of starvation. Between SJF and HRRN scheduling algorithm, the CPU is automatically allotted to the next process which has the highest response ratio.
Level Up Your GATE Prep!
Embark on a transformative journey towards GATE success by choosing
Data Science & AI as your second paper choice with our specialized course. If you find yourself lost in the vast landscape of the GATE syllabus, our program is the compass you need.
Last Updated :
04 Dec, 2023
Like Article
Save Article