Round Robin

Implementing the Round Robin Process Scheduling Algorithm

Program output

Round Robin Scheduling Algorithm

The Round Robin (RR) scheduling algorithm is one of the oldest, simplest, fairest, and most widely used algorithms in operating systems. It dispatches processes in a First-In-First-Out (FIFO) manner but assigns them a limited amount of CPU time known as a time-slice or a quantum. If a process does not complete within its time-slice, the CPU is preempted and given to the next process waiting in the queue. The preempted process is then placed at the back of the ready list. Round Robin Scheduling is preemptive, making it effective in time-sharing environments where the system needs to guarantee reasonable response times for interactive users.

Table of Contents

Introduction

The Round Robin scheduling algorithm provides fairness by allocating CPU time to processes in a cyclic manner. Each process is executed for a fixed time quantum, and if the process doesn’t complete within the quantum, it is preempted and added back to the ready queue. This algorithm is widely implemented in most operating systems and is suitable for time-sharing environments.

Characteristics of Round-Robin Scheduling

Here are the important characteristics of Round-Robin Scheduling:

  • Round Robin is a preemptive algorithm.
  • The CPU is shifted to the next process after a fixed interval of time called a time quantum or time slice.
  • The preempted process is added to the end of the queue.
  • Round Robin is a hybrid model that is clock-driven.
  • The time slice should be a minimum assigned time for a specific task, but it may vary across different operating systems.
  • It is a real-time algorithm that responds to events within a specific time limit.
  • Round Robin is one of the oldest, fairest, and easiest scheduling algorithms.
  • It is a widely used scheduling method in traditional operating systems.

Calculating Average Waiting Time

Average waiting time (AWT) is a crucial parameter to evaluate the performance of any scheduling algorithm. AWT represents the average waiting time of processes in the queue, waiting for the scheduler to select them for execution.

Example Processes

Consider the following set of 5 processes whose arrival time and burst time are given:

Example Processes 1

Example Processes 2

Output

The output of the .py file implementing the Round Robin scheduling algorithm is shown below:

Round Robin Output 1

Round Robin Output 2

Round Robin Output 3

Please refer to the Round Robin Repository for the complete code implementation.

For more information on scheduling algorithms and their analysis, please check the related files and code in this repository.

# Round Robin Algorithm with and without Arrival Time (Preemptive)

# To Find - Turn Around Time and Wait Time and their respective average times

# Functions to sort the list which contains Arrival and Burst Times according to Burst Time

# import libraries
from re import S
from tabulate import tabulate # For printing the result in a Tabular Format
def sorting_burst(l):
    return l[2] # Returns the Third element of the list which is Burst Time
def sorting_arrival(l):
    return l[1] # Returns the Second element of the list which is Arrival Time
def Turn_Around_Time(P, limit):
    # Declaring Variables for Calculating Total Turn Around Time
    total_tat = 0
    for i in range(limit):
        tat = P[i][5] - P[i][1]
        total_tat += tat # Formula For Turn Around Time -> Completion Time - Arrival TIme
        P[i].append(tat) # Appending the Turn Around Time to the List

    avg_tat = total_tat/limit
    return avg_tat
def Waiting_Time(P, limit):
    # Declaring Variables for Calculating Total Waiting Time
    total_wt = 0

    for i in range(limit):
        wt = P[i][6] - P[i][4]
        total_wt += wt # Formula For Waiting Time -> Turn Around Time - Burst Time
        P[i].append(wt) # Appending the Waiting Time to the List

    avg_wt = total_wt/limit
    return avg_wt
def Logic(P, limit, tq):
    
    completed_processes = []
    arrived = [] # Contains Processes which have completed their respective execution
    exit_time = [] # To note the completion time of a process -> the end time of previous process + burst time of current process
    completion_time = 0 # Execution Time for a process

    # Sorting Processes by Arrival Time
    P.sort(key=sorting_arrival)

    while True: # The loop runs till all the processes have been executed successfully
        not_arrived = [] # Contains Processes which have not completed their respective execution
        buffer = []

        for i in range(limit):
            if(P[i][1] <= completion_time and P[i][3] == 0):# Checking whether the arrival time of the process is less
                # than Completion time or not and if the process has not been executed
                a = 0
                if(len(arrived) != 0):
                    for j in range(len(arrived)):
                        if (P[i][0] == arrived[j][0]):
                            a = 1

                if a == 0: # Adding a process once it's completed, to the Arrived list
                    buffer.extend([P[i][0], P[i][1], P[i][2], P[i][4]]) # Appending Process ID, AT, BT and Burst Time which
                    # will be used as Remaineder Time - Time Quantum - Burst Time
                    arrived.append(buffer)
                    buffer = []

                if (len(arrived) != 0 and len(completed_processes) != 0): # Inserting a recently executed process at the
                    # end of the arrived list
                    for j in range(len(arrived)):
                        if(arrived[j][0] == completed_processes[len(completed_processes) - 1]):
                            arrived.insert((len(arrived) - 1), arrived.pop(j))

            elif P[i][3] == 0:
                buffer.extend([P[i][0], P[i][1], P[i][2], P[i][4]]) # Appending Process ID, AT, BT and Burst Time which
                # will be used as Remaineder Time - Time Quantum - Burst Time
                not_arrived.append(buffer)
                buffer = []

        if len(arrived) == 0 and len(not_arrived) == 0:
            break

        if(len(arrived) != 0):
            if arrived[0][2] > tq: # Process has Greater Burst TIme than Time Quantum
                completion_time += tq
                exit_time.append(completion_time)
                completed_processes.append(arrived[0][0])
                for j in range(limit):
                    if(P[j][0] == arrived[0][0]):
                        break
                P[j][2] -= tq # Reducing Time Quantum from Burst time
                arrived.pop(0) # Popping the completed process

            elif (arrived[0][2] <= tq): # If the Burst Time is Less than or Equal to Time Quantum
                completion_time += arrived[0][2]
                exit_time.append(completion_time)
                completed_processes.append(arrived[0][0])
                for j in range(limit):
                    if(P[j][0] == arrived[0][0]):
                        break

                P[j][2] = 0 # Setting the Burst Time as 0 since Process gets executed completely
                P[j][3] = 1 # Setting Completion status as 1 -> implies process has been executed successfully.
                P[j].append(completion_time)
                arrived.pop(0) # Popping the completed process

        elif (len(arrived) == 0):
            if completion_time < not_arrived[0][1]: # Checking completion time with arrival time of process
                # which hasn't been executed
                completion_time = not_arrived[0][1]
            

            if not_arrived[0][2] > tq: # Process has Greater Burst Time than Time Quantum
                completion_time += tq
                exit_time.append(completion_time)
                completed_processes.append(not_arrived[0][0])
                for j in range(limit):
                    if(P[j][0] == not_arrived[0][0]):
                        break
                P[j][2] -= tq # Reducing Time Quantum from Burst time

            elif (not_arrived[0][2] <= tq): # If the Burst Time is Less than or Equal to Time Quantum
                completion_time += not_arrived[0][2]
                exit_time.append(completion_time)
                completed_processes.append(not_arrived[0][0])
                for j in range(limit):
                    if(P[j][0] == not_arrived[0][0]):
                        break

                P[j][2] = 0 # Setting the Burst Time as 0 since Process gets executed completely
                P[j][3] = 1 # Setting Completion status as 1 -> implies process has been executed successfully.
                P[j].append(completion_time)

    tat = Turn_Around_Time(P, limit)
    wt = Waiting_Time(P, limit)

    P.sort(key=sorting_burst) # Sorting the List by Burst Time (Order in which processes are executed)
    headers = ["Process Number", "Arrival Time", "Remainder Burst Time", "Completed Status", "Original Burst Time", "Total Execution Time", "Turn Around Time", "Waiting Time"]
    print(tabulate(P, headers, tablefmt="psql"))

    # Printing the Average Waiting and Turn Around Time
    print("\nAverage Waiting Time is = ", round(wt, 2)) # Rounding off Average Waiting Time to 2 Decimal places
    print("Average Turn Around Time is = ", round(tat, 2)) # Rounding off Average Turn Around Time to 2 Decimal places
def main():
    run = True
    while(run):
        
        # Declaring arrays
        processes = []
        
        print("\nMenu\nDo you want to assume : \n1. Arrival Time as 0\n2. Input Arrival Time\n3. Exit\n")
        ch = int(input("Enter Your Choice : "))

        if ch == 1:
            limit_process = int(input("Enter the Number of Processes : "))
            for i in range(limit_process):
                p = []
                arrival = 0
                burst = int(input("Enter the Burst Time for process {} : ".format(i)))
                process_id = "P" + str(i + 1)

                p.extend([process_id, arrival, burst, 0, burst]) # Forming a list of info entered by the user, 0 is for completion status
                processes.append(p)

            time_quantum = int(input("Enter the Time Quantum : ")) # Inputting Time Quantum from user

            Logic(processes , limit_process, time_quantum)
            run = int(input("\nWant to continue? (Yes = Input 1/false = Input 0) : "))

        elif ch == 2:
            limit_process = int(input("Enter the Number of Processes : "))
            for i in range(limit_process):
                p = []
                arrival = int(input("Enter the Arrival Time for process {} : ".format(i)))
                burst = int(input("Enter the Burst Time for process {} : ".format(i)))
                process_id = "P" + str(i + 1)

                p.extend([process_id, arrival, burst, 0, burst])
                processes.append(p)

            time_quantum = int(input("Enter the Time Quantum : ")) # Inputting Time Quantum from user

            Logic(processes, limit_process, time_quantum)
            run = int(input("\nWant to continue? (Yes = Input 1/false = Input 0) : "))
        
        elif ch == 3:
            print("Thank You!")
            exit(0)

        else:
            print("Invalid Choice!")
            run = int(input("\nWant to continue? (Yes = Input 1/false = Input 0) : "))
main()
Menu
Do you want to assume : 
1. Arrival Time as 0
2. Input Arrival Time
3. Exit

Enter Your Choice : 2
Enter the Number of Processes : 5
Enter the Arrival Time for process 0 : 0
Enter the Burst Time for process 0 : 5
Enter the Arrival Time for process 1 : 1
Enter the Burst Time for process 1 : 3
Enter the Arrival Time for process 2 : 2
Enter the Burst Time for process 2 : 1
Enter the Arrival Time for process 3 : 3
Enter the Burst Time for process 3 : 2
Enter the Arrival Time for process 4 : 4
Enter the Burst Time for process 4 : 3
Enter the Time Quantum : 2
+------------------+----------------+------------------------+--------------------+-----------------------+------------------------+--------------------+----------------+
| Process Number   |   Arrival Time |   Remainder Burst Time |   Completed Status |   Original Burst Time |   Total Execution Time |   Turn Around Time |   Waiting Time |
|------------------+----------------+------------------------+--------------------+-----------------------+------------------------+--------------------+----------------|
| P1               |              0 |                      0 |                  1 |                     5 |                     13 |                 13 |              8 |
| P2               |              1 |                      0 |                  1 |                     3 |                     12 |                 11 |              8 |
| P3               |              2 |                      0 |                  1 |                     1 |                      5 |                  3 |              2 |
| P4               |              3 |                      0 |                  1 |                     2 |                      9 |                  6 |              4 |
| P5               |              4 |                      0 |                  1 |                     3 |                     14 |                 10 |              7 |
+------------------+----------------+------------------------+--------------------+-----------------------+------------------------+--------------------+----------------+

Average Waiting Time is =  5.8
Average Turn Around Time is =  8.6

Want to continue? (Yes = Input 1/false = Input 0) : 0

Edit this page

Srihari Thyagarajan
Srihari Thyagarajan
B Tech AI Senior Student

Hi, I’m Haleshot, a final-year student studying B Tech Artificial Intelligence. I like projects relating to ML, AI, DL, CV, NLP, Image Processing, etc. Currently exploring Python, FastAPI, projects involving AI and platforms such as HuggingFace and Kaggle.

Next
Previous

Related