'''
Round Robin Scheduling Algorithm
The task is to find the Average Waiting Time and Average Turnaround Time of the given processes with their Burst Time using Round Robin Scheduling Algorithm.
Round Robin is a scheduling policy that selects the waiting process and executes it for a fixed time quantum
Round Robin is a Pre-emptive Algorithm, hence the process will execute for a fixed time quantum and then it is switched and another process is executed
Round Robin is cyclic in nature so it does not cause starvation
We will consider processes having Arrival Time as 0.
Start Time: Time at which the execution of the process starts
Completion Time: Time at which the process completes its execution
Turnaround Time: Completion Time - Arrival Time
Waiting Time: Turnaround Time - Burst Time
'''
class RoundRobin:
def processData(self, no_of_processes):
process_data = []
for i in range(no_of_processes):
temporary = []
process_id = int(input("Enter Process ID: "))
burst_time = int(input(f"Enter Burst Time for Process {process_id}: "))
temporary.extend([process_id, 0, burst_time, 0, burst_time])
'''
'0' is the state of the process. 0 means not executed and 1 means execution complete
'''
process_data.append(temporary)
time_slice = int(input("Enter Time Slice: "))
RoundRobin.schedulingProcess(self, process_data, time_slice)
def schedulingProcess(self, process_data, time_slice):
start_time = []
exit_time = []
executed_process = []
ready_queue = []
s_time = 0
while 1:
temp = []
for i in range(len(process_data)):
if process_data[i][1] <= s_time and process_data[i][3] == 0:
present = 0
if len(ready_queue) != 0:
for k in range(len(ready_queue)):
if process_data[i][0] == ready_queue[k][0]:
present = 1
'''
The above if loop checks that the next process is not a part of ready_queue
'''
if present == 0:
temp.extend([process_data[i][0], process_data[i][1], process_data[i][2], process_data[i][4]])
ready_queue.append(temp)
temp = []
'''
The above if loop adds a process to the read_queue only if it is not already present in it
'''
if len(ready_queue) != 0 and len(executed_process) != 0:
for k in range(len(ready_queue)):
if ready_queue[k][0] == executed_process[len(executed_process) - 1]:
ready_queue.insert((len(ready_queue) - 1), ready_queue.pop(k))
'''
The above if loop makes sure that the recently executed process is appended at the end of ready_queue
'''
if len(ready_queue) == 0:
break
if len(ready_queue) != 0:
if ready_queue[0][2] > time_slice:
'''
If process has remaining burst time greater than the time slice, it will execute for a time period equal to time slice and then switch
'''
start_time.append(s_time)
s_time = s_time + time_slice
e_time = s_time
exit_time.append(e_time)
executed_process.append(ready_queue[0][0])
for j in range(len(process_data)):
if process_data[j][0] == ready_queue[0][0]:
break
process_data[j][2] = process_data[j][2] - time_slice
ready_queue.pop(0)
elif ready_queue[0][2] <= time_slice:
'''
If a process has a remaining burst time less than or equal to time slice, it will complete its execution
'''
start_time.append(s_time)
s_time = s_time + ready_queue[0][2]
e_time = s_time
exit_time.append(e_time)
executed_process.append(ready_queue[0][0])
for j in range(len(process_data)):
if process_data[j][0] == ready_queue[0][0]:
break
process_data[j][2] = 0
process_data[j][3] = 1
process_data[j].append(e_time)
ready_queue.pop(0)
t_time = RoundRobin.calculateTurnaroundTime(self, process_data)
w_time = RoundRobin.calculateWaitingTime(self, process_data)
RoundRobin.printData(self, process_data, t_time, w_time, executed_process)
def calculateTurnaroundTime(self, process_data):
total_turnaround_time = 0
for i in range(len(process_data)):
turnaround_time = process_data[i][5] - process_data[i][1]
'''
turnaround_time = completion_time - arrival_time
'''
total_turnaround_time = total_turnaround_time + turnaround_time
process_data[i].append(turnaround_time)
average_turnaround_time = total_turnaround_time / len(process_data)
'''
average_turnaround_time = total_turnaround_time / no_of_processes
'''
return average_turnaround_time
def calculateWaitingTime(self, process_data):
total_waiting_time = 0
for i in range(len(process_data)):
waiting_time = process_data[i][6] - process_data[i][4]
'''
waiting_time = turnaround_time - burst_time
'''
total_waiting_time = total_waiting_time + waiting_time
process_data[i].append(waiting_time)
average_waiting_time = total_waiting_time / len(process_data)
'''
average_waiting_time = total_waiting_time / no_of_processes
'''
return average_waiting_time
def printData(self, process_data, average_turnaround_time, average_waiting_time, executed_process):
process_data.sort(key=lambda x: x[0])
'''
Sort processes according to the Process ID
'''
print(
"Process_ID Arrival_Time Rem_Burst_Time Completed Original_Burst_Time Completion_Time Turnaround_Time Waiting_Time")
for i in range(len(process_data)):
for j in range(len(process_data[i])):
print(process_data[i][j], end="\t\t\t\t")
print()
print(f'Average Turnaround Time: {average_turnaround_time}')
print(f'Average Waiting Time: {average_waiting_time}')
print(f'Sequence of Processes: {executed_process}')
if __name__ == "__main__":
no_of_processes = int(input("Enter number of processes: "))
rr = RoundRobin()
rr.processData(no_of_processes)
Output: