Shortest Job First (SJF) Scheduling with Examples and Programs!

Hi Learners! Today, you will learn about what is shortest job first scheduling in OS and its examples? As well as, shortest job first scheduling program in C, C++, and Java with their output. This is unique blog post over the internet; therefore, at the end of this article; you will definitely fully understand about Shortest Job First Scheduling in OS without any hassle.

What is Shortest Job First Scheduling?

Shortest Job First (SJF) is a CPU scheduling algorithm that selects the process with the shortest burst time, i.e., the amount of time a process requires to complete its execution, for execution. This algorithm is non-preemptive, which means that once a process starts executing, it runs until it completes or blocks for input/output (I/O).

shortest-job-first-scheduling

The basic principle of SJF scheduling is to minimize the average waiting time of the processes in the ready queue by selecting the process that requires the least amount of time to complete. This algorithm is particularly useful in scenarios where there is a mix of long and short processes. Short processes can get executed quickly, while long processes may have to wait.

‘SJF Scheduling’ Tutorial Headlines:

In this section, we will show you all headlines about this entire article; you can check them as your choice; below shown all:

  1. What is Shortest Job First Scheduling?
  2. What are the Types of Shortest Jobs First Scheduling?
  • Pre-Emptive SJF Scheduling
  • Non Pre-Emptive SJF Scheduling
  1. What is a Real Life Example of Shortest Job First Scheduling?
  2. Shortest job First Algorithm Implementation
  3. What are the Advantages and Disadvantages of SJF Scheduling?
  • Advantages of SJF Scheduling
  • Disadvantages of SJF Scheduling
  1. Characteristics of SJF Scheduling
  2. Shortest Job First Scheduling Program in C with Arrival Time
  3. Shortest Job First Scheduling Program in C++ with Arrival Time
  4. Shortest Job First Scheduling Program in Java with Arrival Time

Let’s Get Started!!         

What are the Types of Shortest Jobs First Scheduling?

There are two different types of SJF scheduling algorithm; below shown each one in detail, you can show them:

Also Read: Priority Scheduling Algorithm in OS with Examples & Programs!!

Pre-Emptive SJF Scheduling:

Pre-emptive Shortest Job First (SJF) scheduling is a CPU scheduling algorithm in which the process with the shortest burst time is executed first. In pre-emptive SJF, if a new process arrives with a shorter burst time than the currently executing process, the CPU is pre-empted and the new process is executed.

The main objective of pre-emptive SJF is that it reduces the average waiting time of processes by prioritizing short processes. However, it may lead to starvation of long processes since short processes are always given priority. To avoid this, a time quantum can be set so that long processes are given a chance to execute after a certain amount of time has elapsed.

Pre-emptive SJF is more efficient than non-preemptive SJF since it allows the CPU to switch to a new process as soon as a shorter process arrives. However, it may result in more context switches, which can cause overhead and slow down the system.

Shortest job First Scheduling Pre-Emptive Example

Sure, here’s an example of Shortest Job First (SJF) scheduling with preemption:

Suppose we have three processes, P1, P2, and P3, with the following burst times:

Process         Burst Time

P1                             4

P2                             2

P3                              6

The SJF scheduling algorithm selects the process with the shortest burst time first. In this case, P2 has the shortest burst time of 2 units, so it is selected to run first. After running for 1 unit, a new process arrives with a shorter burst time than P2, so P2 is pre-empted and the new process is run. The remaining processes are then scheduled in order of shortest to longest burst time.

Here is the sequence of execution using SJF with preemption:

Time      Running Process

0              None (arrival of P1, P2, and P3)

1              P2

2              P1

3              P1

4              P3

5              P3

6              P3

7              None (all processes complete)

The total waiting time for this sequence is (1-0) + (2-1) + (4-2) = 4 units, and the average waiting time is 4/3 = 1.33 units.

Non Pre-Emptive SJF Scheduling:

Non-Preemptive SJF (Shortest Job First) scheduling is a type of CPU scheduling algorithm that is used in operating systems to prioritize tasks based on their execution time. In this algorithm, the process with the shortest execution time is given the highest priority for execution.

Also Read: Round Robin Scheduling Algorithm with Examples and Programs!!

The non-preemptive SJF scheduling algorithm operates in a simple manner. When a process arrives, it is compared with the currently running process. If the arriving process has a shorter execution time than the currently running process, then it is scheduled for execution next. Otherwise, it is added to the ready queue to wait for its turn to be executed.

One limitation of the non-preemptive SJF scheduling algorithm is that it is susceptible to the problem of starvation. If a long-running process is continuously added to the end of the ready queue, then short processes may never get a chance to execute, resulting in starvation.

To mitigate this issue, some operating systems use techniques such as aging, where the priority of a process increases as it waits in the ready queue, ensuring that eventually, every process gets executed.

Therefore, the non-preemptive SJF scheduling algorithm is a simple and efficient way to schedule processes based on their execution time, but it may suffer from the problem of starvation if not implemented with appropriate techniques.

Shortest Job First Scheduling Non Pre-Emptive Example

Shortest Job First (SJF) scheduling algorithm has another type that is non-preemptive CPU scheduling algorithm in which the process with the shortest burst time is executed first. In case of a tie, the process with the lowest process ID is executed first.

Here is an example of SJF scheduling algorithm with three processes:

Process          Arrival Time    Burst Time

P1                           0                    4

P2                           1                    3

P3                           2                    2

Assuming the processes arrive in the order listed above, the Gantt chart for the execution of these processes using SJF algorithm would be:

Process                               P3           P2           P1

Time                      2              5              9

The average waiting time for the above example can be calculated as follows:

Average Waiting Time = ((2-2) + (5-1) + (9-2)) / 3

= 4 / 3

= 1.33 units of time

Note that the first process P1 has a higher burst time compared to the other two processes, but it is executed last because it arrives first. The SJF algorithm prioritizes shorter burst time over arrival time.

What is a Real Life Example of Shortest Job First Scheduling?

As you know about SJF scheduling algorithm, it selects the waiting process with the smallest execution time to be executed next. A real-life example of SJF scheduling can be seen in a fast-food restaurant.

Also Read: Process Life Cycle in Operating System | Process State in OS

Assume there are three orders to be processed:

Order 1: A hamburger and a small fries

Order 2: A burger, a large fries, and a drink

Order 3: A chicken sandwich and a drink

If the restaurant uses SJF scheduling, the order with the smallest preparation time will be processed first. Therefore, the kitchen staff will prioritize Order 1 (hamburger and small fries), which can be prepared quickly. Once Order 1 is ready, it will be served to the customer, and the kitchen staff will move on to prepare the next order with the smallest execution time, which is Order 3 (chicken sandwich and a drink). Finally, they will prepare Order 2, which requires the most preparation time. By using SJF scheduling, the restaurant can optimize its process and reduce customer waiting time.

Shortest job First Algorithm Implementation

Here’s a simple workflow chart for the Shortest Job First (SJF) scheduling algorithm:

Also Read: First Come First Serve (FCFS) Scheduling Algorithm in OS with Examples & Programs!!

  1. Start
  2. Read in the number of processes and their burst times
  3. Sort the processes based on their burst times (shortest to longest)
  4. Set the current time to 0
  5. While there are still processes remaining to be executed:

                If the current process has arrived (arrival time <= current time):

  • Execute the current process for its burst time
  • Add its waiting time to the total waiting time
  • Increment the current time by the process’s burst time

                If the current process has not arrived:

                  Increment the current time until the next process arrives

  1. Calculate the average waiting time as total waiting time divided by the number of processes
  2. Display the average waiting time
  3. Stop

In this workflow, all processes arrive at time 0. If there are different arrival times, you will need to modify the algorithm accordingly.

What are the Advantages and Disadvantages of SJF Scheduling?

Here are some advantages and disadvantages of SJF scheduling:

Advantages of SJF Scheduling

The primary advantage of SJF scheduling is that it reduces the average waiting time of processes by giving preference to shorter jobs.

Also Read: What is Process in OS? Types of Process in Operating System!!

Here are some specific advantages of SJF scheduling:

Reduced Average Waiting Time: As mentioned, SJF scheduling reduces the average waiting time of processes. This is because shorter jobs are given priority, which means they are completed faster, freeing up the CPU for other jobs.

Improved System Performance: SJF scheduling can lead to improved system performance because it ensures that the CPU is always working on the most critical task. This can help to increase the overall throughput of the system and make it more efficient.

Fairness: SJF scheduling can be considered a fair scheduling algorithm because it ensures that all jobs are executed in the shortest time possible. This means that smaller jobs are not kept waiting unnecessarily while larger jobs hog the CPU.

Minimal Starvation: SJF scheduling can minimize the occurrence of starvation, which happens when a process is never given the chance to execute because it is continuously pre-empted by other, longer-running processes. SJF scheduling ensures that all processes are executed as soon as possible, which reduces the likelihood of starvation.

Overall, SJF scheduling is an effective scheduling algorithm that can improve system performance and reduce the average waiting time of processes, leading to a more efficient and fair system.

Disadvantages of SJF Scheduling

While SJF has some advantages, it also has several disadvantages, including:

Complexity: SJF requires knowledge of the run time of each process to determine the shortest job. This information is not always readily available and can be difficult to estimate accurately, especially for long-running processes.

Starvation: The SJF algorithm can lead to starvation of longer processes, as the scheduler always selects the shortest job next. Longer processes may have to wait indefinitely for shorter processes to complete, leading to poor overall system performance.

Delay: SJF can also result in delays if a long process is introduced after a shorter one has started. The long process may have to wait until the short process is completed, causing a delay.

Pre-Emption: To avoid starvation, SJF may use preemption to stop a currently executing job to start another shorter job. This introduces overhead and can negatively impact system performance.

Inaccuracy: Inaccurate estimations of the run time of a job can cause problems. If the system overestimates the run time of a job, it may be starved of resources unnecessarily, leading to poor performance. If the system underestimates the run time of a job, it may cause delays and poor system performance.

Characteristics of SJF Scheduling

Here, we will show about some of the characteristics of SJF scheduling, aS follow them:

Also Read: Multiprogramming Operating System: Example, Types, and Advantage!!

Non Pre-Emptive: Once a process starts executing, it cannot be preempted until it completes its execution or until a shorter process arrives.

Predictable: SJF scheduling is predictable, as the process with the shortest burst time is always selected next.

Optimal for Minimizing Average Waiting Time: SJF scheduling is optimal for minimizing the average waiting time of processes, as it prioritizes shorter processes over longer ones.

It Can Lead to Starvation: If a process with a long burst time is continuously preempted by processes with shorter burst times, it may never get a chance to execute, leading to starvation.

Requires knowledge of the Burst Time: To implement SJF scheduling, the operating system needs to know the burst time of each process beforehand. This information can be obtained either through previous execution history or by estimation.

May Not be Fair: SJF scheduling may not be fair to long-running processes, as they have to wait longer to get CPU time compared to shorter processes.

Shortest Job First Scheduling Program in C with Arrival Time

Here is an example of a Shortest-Job-First scheduling program in C with arrival time. In this program, the user is asked to enter the number of processes, their arrival times, and burst times. The program then sorts the processes based on their arrival times and uses the Shortest-Job-First scheduling algorithm to calculate the waiting time, turnaround time, and average waiting time.

#include<stdio.h>

#include<stdlib.h>

struct process {

    int pid; // process ID

    int arrival_time; // arrival time

    int burst_time; // burst time

    int waiting_time; // waiting time

    int turnaround_time; // turnaround time

};

void swap(struct process *xp, struct process *yp) {

    struct process temp = *xp;

    *xp = *yp;

    *yp = temp;

}

void sort(struct process *p, int n) {

    int i, j;

    for (i = 0; i < n-1; i++) {

        for (j = 0; j < n-i-1; j++) {

            if (p[j].arrival_time > p[j+1].arrival_time) {

                swap(&p[j], &p[j+1]);

            }

        }

    }

}

void sjf(struct process *p, int n) {

    int i, j;

    int total_waiting_time = 0, total_turnaround_time = 0;

    p[0].waiting_time = 0;

    for (i = 1; i < n; i++) {

        p[i].waiting_time = p[i-1].burst_time + p[i-1].waiting_time;

    }

    for (i = 0; i < n; i++) {

        p[i].turnaround_time = p[i].burst_time + p[i].waiting_time;

    }

    for (i = 0; i < n; i++) {

        total_waiting_time += p[i].waiting_time;

        total_turnaround_time += p[i].turnaround_time;

    }

    printf(“Process\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\n”);

    for (i = 0; i < n; i++) {

        printf(“%d\t\t%d\t\t%d\t\t%d\t\t%d\n”, p[i].pid, p[i].arrival_time, p[i].burst_time, p[i].waiting_time, p[i].turnaround_time);

    }

    printf(“Average Waiting Time = %.2f\n”, (float) total_waiting_time / (float) n);

    printf(“Average Turnaround Time = %.2f\n”, (float) total_turnaround_time / (float) n);

}

int main() {

    int n, i;

    printf(“Enter the number of processes: “);

    scanf(“%d”, &n);

    struct process p[n];

    for (i = 0; i < n; i++) {

        printf(“Enter the arrival time of process %d: “, i+1);

        scanf(“%d”, &p[i].arrival_time);

        printf(“Enter the burst time of process %d: “, i+1);

        scanf(“%d”, &p[i].burst_time);

        p[i].pid = i+1;

    }

    sort(p, n);

    sjf(p, n);

    return 0;

}

In this program, the struct process is used to represent each process. The swap function is used to swap two processes, and the sort function is used to sort the processes based on their arrival times. The sjf function is used to calculate the waiting time, turnaround time, and average waiting time.

Shortest Job First Scheduling Program in C++ with Arrival Time

Here is an example of a C++ program that implements the Shortest-Job-First (SJF) scheduling algorithm with arrival time:

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

// Process structure

struct process {

    int id;             // process ID

    int arrival_time;   // arrival time of the process

    int burst_time;     // burst time of the process

};

// Comparison function for sorting processes by burst time

bool compare_burst_time(const process &p1, const process &p2) {

    return p1.burst_time < p2.burst_time;

}

int main() {

    int n;  // number of processes

    cout << “Enter the number of processes: “;

    cin >> n;

    vector<process> processes(n);  // vector to store processes

    // Read input

    for (int i = 0; i < n; i++) {

        cout << “Enter the arrival time and burst time of process ” << i + 1 << “: “;

        cin >> processes[i].arrival_time >> processes[i].burst_time;

        processes[i].id = i + 1;

    }

    // Sort processes by arrival time

    sort(processes.begin(), processes.end(), [](process p1, process p2) {

        return p1.arrival_time < p2.arrival_time;

    });

    // Initialize variables

    int total_waiting_time = 0;

    int total_turnaround_time = 0;

    int current_time = processes[0].arrival_time;

    // Process scheduling

    for (int i = 0; i < n; i++) {

        // Find the process with the shortest burst time that has arrived

        int shortest_job = -1;

        for (int j = 0; j < n; j++) {

            if (processes[j].arrival_time <= current_time && processes[j].burst_time > 0) {

                if (shortest_job == -1 || processes[j].burst_time < processes[shortest_job].burst_time) {

                    shortest_job = j;

                }

            }

        }

        // Execute the shortest job

        int remaining_time = processes[shortest_job].burst_time;

        current_time += remaining_time;

        processes[shortest_job].burst_time = 0;

        // Update waiting time and turnaround time

        int waiting_time = current_time – processes[shortest_job].arrival_time – remaining_time;

        total_waiting_time += waiting_time;

        total_turnaround_time += waiting_time + processes[shortest_job].burst_time;

        // Output execution log

        cout << “Process ” << processes[shortest_job].id << ” executed from ” << current_time – remaining_time << ” to ” << current_time << endl;

    }

    // Output results

    double average_waiting_time = (double) total_waiting_time / n;

    double average_turnaround_time = (double) total_turnaround_time / n;

    cout << “Average waiting time: ” << average_waiting_time << endl;

    cout << “Average turnaround time: ” << average_turnaround_time << endl;

    return 0;

}

In this program, the process structure represents a process with an ID, an arrival time, and a burst time. The compare_burst_time function is used to sort processes by burst time. The main function first reads input from the user and stores the processes in a vector. It then sorts the processes by arrival time and initializes some variables. The SJF scheduling algorithm is implemented in the loop that processes the jobs

Shortest Job First Scheduling Program in Java with Arrival Time

Here is a Java program for Shortest-Job-First (SJF) scheduling with arrival time:

import java.util.*;

class Process {

    int pid;

    int arrivalTime;

    int burstTime;

    int completionTime;

    int turnaroundTime;

    int waitingTime;

    boolean isCompleted;

        Process(int pid, int arrivalTime, int burstTime) {

        this.pid = pid;

        this.arrivalTime = arrivalTime;

        this.burstTime = burstTime;

        this.isCompleted = false;

    }

}

public class SJFScheduling {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        System.out.print(“Enter the number of processes: “);

        int n = sc.nextInt();

        List<Process> processes = new ArrayList<>();

        for (int i = 1; i <= n; i++) {

            System.out.print(“Enter arrival time and burst time for process ” + i + “: “);

            int arrivalTime = sc.nextInt();

            int burstTime = sc.nextInt();

            processes.add(new Process(i, arrivalTime, burstTime));

        }

                // sort processes by arrival time

        processes.sort(Comparator.comparingInt(p -> p.arrivalTime));

        int currentTime = 0;

        float avgTurnaroundTime = 0;

        float avgWaitingTime = 0;

        for (Process p : processes) {

            while (currentTime < p.arrivalTime) {

                currentTime++;

            }

            p.completionTime = currentTime + p.burstTime;

            p.turnaroundTime = p.completionTime – p.arrivalTime;

            p.waitingTime = p.turnaroundTime – p.burstTime;

            avgTurnaroundTime += p.turnaroundTime;

            avgWaitingTime += p.waitingTime;

            currentTime = p.completionTime;

        }

         System.out.println(“\nProcess\tArrival Time\tBurst Time\tCompletion Time\tTurnaround Time\tWaiting Time”);

        for (Process p : processes) {

            System.out.println(p.pid + “\t\t” + p.arrivalTime + “\t\t” + p.burstTime + “\t\t” + p.completionTime + “\t\t” + p.turnaroundTime + “\t\t” + p.waitingTime);

        }

        System.out.println(“\nAverage Turnaround Time: ” + (avgTurnaroundTime/n));

        System.out.println(“Average Waiting Time: ” + (avgWaitingTime/n));

    }

}

Here’s a brief explanation of the code:

We define a Process class to store information about each process, including the process ID, arrival time, burst time, completion time, turnaround time, waiting time, and whether the process has been completed yet.

In the main() method, we prompt the user to enter the number of processes and their arrival and burst times. We then create a list of Process objects and add each process to the list.

We sort the list of processes by arrival time using a comparator.

We initialize the current time to 0 and loop through each process. If the current time is less than the process’s arrival time, we increment the current time until it reaches the process’s arrival time. We then calculate the completion time, turnaround time, and waiting time for the process and update the average turnaround time and average waiting time. Finally, we set the current time to the process’s completion time.

After processing all the processes, we print out a table of results and the average turnaround time and average waiting time.

Note that this implementation assumes that all processes arrive at different times. If two or more processes arrive at the same time, the one with

The Final Words

Now, we can make ensure that you have been fully understood about what is shortest job first scheduling in OS and its examples? As well as, shortest job first scheduling program in C, C++, and Java with their output. If this article is helpful for you, then please share it along with your friends, family members or relatives over social media platforms like as Facebook, Instagram, Linked In, Twitter, and more.

Also Read: Multitasking Operating System? Example, Types, and Advantages!!

If you have any experience, tips, tricks, or query regarding this issue? You can drop a comment!

Happy Learning!!

Leave a Reply

Your email address will not be published. Required fields are marked *