Skip to content

Instantly share code, notes, and snippets.

@nicholaskajoh
Last active February 20, 2019 12:11
Show Gist options
  • Save nicholaskajoh/d575be5429887d8c4f2b715a18b54295 to your computer and use it in GitHub Desktop.
Save nicholaskajoh/d575be5429887d8c4f2b715a18b54295 to your computer and use it in GitHub Desktop.
Round Robin Scheduling Algorithm
import random
import matplotlib.pyplot as plt
import numpy as np
def generateWorkload():
n = 20 # size of workload
inter_arrival_time_range = (1, 15) # nanoseconds
burst_time_range = (70, 130) # nanoseconds
processes = []
for i in range(n):
arrival_time = random.randint(*inter_arrival_time_range)
burst_time = random.randint(*burst_time_range)
processes.append({
'process_name': 'P' + str(i),
'arrival_time': 0 if i == 0 else arrival_time + processes[i - 1]['arrival_time'],
'burst_time': burst_time,
'waiting_time': 0,
'time_to_burst': burst_time,
'completion_time': -1,
})
processes = sorted(processes, key=lambda process: process['arrival_time']) # sort processes by arrival time
return processes
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def peek(self):
return self.items[-1]
def getItems(self):
return self.items
def roundRobin(q):
process_queue = Queue()
all_processes = generateWorkload()
time = 0
idle_time = 0
MAX_IDLE_TIME = 500
redux = []
is_idle = True
current_process_time = 0
while idle_time < MAX_IDLE_TIME:
# find all processes that have arrived and enqueue them
for process in all_processes:
if process['arrival_time'] == time:
process_queue.enqueue(process)
# give next process in queue cpu time
if is_idle and process_queue.size() > 0:
is_idle = False
current_process = process_queue.peek()
redux.append({
'process_name': current_process['process_name'],
'action': 'IN',
'time': time,
})
# dequeue if process has been completed
if process_queue.size() > 0:
current_process = process_queue.peek()
if current_process['time_to_burst'] == 0:
process_queue.dequeue()
current_process['completion_time'] = time
is_idle = True
# dequeue process if quantum time has been exausted
# enqueue same process if it hasn't yet been completed
if current_process_time == q and process_queue.size() > 0:
current_process_time = 0
is_idle = True
dequeued_process = process_queue.dequeue()
if dequeued_process['time_to_burst'] > 0:
process_queue.enqueue(dequeued_process)
redux.append({
'process_name': dequeued_process['process_name'],
'action': 'OUT',
'time': time,
})
# update time
if is_idle:
idle_time += 1
else:
current_process_time += 1
current_process = process_queue.peek()
current_process['time_to_burst'] -= 1
time += 1
if process_queue.size() > 0:
current_process = process_queue.peek()
processes_in_queue = process_queue.getItems()
for process in processes_in_queue:
if process != current_process:
process['waiting_time'] += 1
waiting_times = []
turn_around_times = []
for process in all_processes:
waiting_times.append(process['waiting_time'])
turn_around_times.append(process['completion_time'] - process['arrival_time'])
average_waiting_time = sum(waiting_times) / float(len(waiting_times))
average_turn_around_time = sum(turn_around_times) / float(len(turn_around_times))
num_context_switches = len(redux) - 1 # minus first process that enters the cpu
# print processes
print('q =', q)
for process in all_processes:
print(process)
print('\n')
return (num_context_switches, average_waiting_time, average_turn_around_time, redux)
def drawHistogram(figure, data, y_label):
figure = plt.figure(figure)
x = np.arange(3)
plt.bar(x, data)
plt.xticks(x, ['q=10', 'q=25', 'q=50'])
plt.ylabel(y_label)
return figure
def drawTimeSeries(figure, redux, title):
x, y, ylabels = [], [], []
processes = set()
for event in redux:
x.append(event['time'])
ylabels.append(event['process_name'])
processes.add(event['process_name'])
processes = list(processes)
for ylabel in ylabels:
y.append(processes.index(ylabel))
fig, ax = plt.subplots()
fig.suptitle(title, fontsize=12)
ax.plot(x, y, '-o', markersize=1)
ax.yaxis.set_ticks(np.arange(len(processes)))
ax.yaxis.set_ticklabels(processes)
plt.xlabel("Time")
plt.ylabel("Process")
return fig
if __name__ =="__main__":
qs = [10, 25, 50]
average_tats = [] # turn around times
average_wts = [] # waiting times
numbers_css = [] # numbers of context switches
tseries_plots = [None, None, None]
for q in qs:
num_context_switches, average_waiting_time, average_turn_around_time, redux = roundRobin(q)
average_tats.append(average_turn_around_time)
average_wts.append(average_waiting_time)
numbers_css.append(num_context_switches)
tseries_plots[qs.index(q)] = drawTimeSeries(qs.index(q) + 1, redux, 'Time series for q=' + str(q))
fig1 = drawHistogram(8, average_tats, 'Average turn around time (ns)')
fig2 = drawHistogram(9, average_wts, 'Average waiting time (ns)')
fig3 = drawHistogram(10, numbers_css, 'Number of context switches')
fig1.show()
fig2.show()
fig3.show()
tseries_plots[0].show()
tseries_plots[1].show()
tseries_plots[2].show()
input()
# Comment on the effect of the different values of Q on the behavior of the algorithm based on the histogram
# Larger values of Q lead to shorter turn around times, waiting times and number of context switches, and vice versa
# A larger time quantum (Q) is therefore recommended when scheduling processes with Round Robin
@nicholaskajoh
Copy link
Author

SAMPLE OUTPUT

q = 10
{'process_name': 'P0', 'arrival_time': 0, 'burst_time': 72, 'waiting_time': 1045, 'time_to_burst': 0, 'completion_time': 1124}
{'process_name': 'P1', 'arrival_time': 5, 'burst_time': 122, 'waiting_time': 1915, 'time_to_burst': 0, 'completion_time': 2055}
{'process_name': 'P2', 'arrival_time': 18, 'burst_time': 120, 'waiting_time': 1988, 'time_to_burst': 0, 'completion_time': 2139}
{'process_name': 'P3', 'arrival_time': 22, 'burst_time': 85, 'waiting_time': 1716, 'time_to_burst': 0, 'completion_time': 1833}
{'process_name': 'P4', 'arrival_time': 32, 'burst_time': 76, 'waiting_time': 1387, 'time_to_burst': 0, 'completion_time': 1503}
{'process_name': 'P5', 'arrival_time': 40, 'burst_time': 84, 'waiting_time': 1587, 'time_to_burst': 0, 'completion_time': 1720}
{'process_name': 'P6', 'arrival_time': 41, 'burst_time': 124, 'waiting_time': 2023, 'time_to_burst': 0, 'completion_time': 2202}
{'process_name': 'P7', 'arrival_time': 43, 'burst_time': 106, 'waiting_time': 1887, 'time_to_burst': 0, 'completion_time': 2047}
{'process_name': 'P8', 'arrival_time': 55, 'burst_time': 129, 'waiting_time': 2014, 'time_to_burst': 0, 'completion_time': 2212}
{'process_name': 'P9', 'arrival_time': 58, 'burst_time': 102, 'waiting_time': 1896, 'time_to_burst': 0, 'completion_time': 2067}
{'process_name': 'P10', 'arrival_time': 62, 'burst_time': 118, 'waiting_time': 1963, 'time_to_burst': 0, 'completion_time': 2155}
{'process_name': 'P11', 'arrival_time': 65, 'burst_time': 77, 'waiting_time': 1531, 'time_to_burst': 0, 'completion_time': 1681}
{'process_name': 'P12', 'arrival_time': 77, 'burst_time': 104, 'waiting_time': 2000, 'time_to_burst': 0, 'completion_time': 2193}
{'process_name': 'P13', 'arrival_time': 82, 'burst_time': 79, 'waiting_time': 1537, 'time_to_burst': 0, 'completion_time': 1706}
{'process_name': 'P14', 'arrival_time': 84, 'burst_time': 110, 'waiting_time': 1959, 'time_to_burst': 0, 'completion_time': 2165}
{'process_name': 'P15', 'arrival_time': 97, 'burst_time': 74, 'waiting_time': 1536, 'time_to_burst': 0, 'completion_time': 1715}
{'process_name': 'P16', 'arrival_time': 104, 'burst_time': 90, 'waiting_time': 1804, 'time_to_burst': 0, 'completion_time': 2007}
{'process_name': 'P17', 'arrival_time': 106, 'burst_time': 95, 'waiting_time': 1893, 'time_to_burst': 0, 'completion_time': 2104}
{'process_name': 'P18', 'arrival_time': 117, 'burst_time': 123, 'waiting_time': 1963, 'time_to_burst': 0, 'completion_time': 2217}
{'process_name': 'P19', 'arrival_time': 120, 'burst_time': 112, 'waiting_time': 1937, 'time_to_burst': 0, 'completion_time': 2181}


q = 25
{'process_name': 'P0', 'arrival_time': 0, 'burst_time': 125, 'waiting_time': 1769, 'time_to_burst': 0, 'completion_time': 1899}
{'process_name': 'P1', 'arrival_time': 5, 'burst_time': 86, 'waiting_time': 1165, 'time_to_burst': 0, 'completion_time': 1260}
{'process_name': 'P2', 'arrival_time': 18, 'burst_time': 94, 'waiting_time': 1257, 'time_to_burst': 0, 'completion_time': 1373}
{'process_name': 'P3', 'arrival_time': 20, 'burst_time': 73, 'waiting_time': 915, 'time_to_burst': 0, 'completion_time': 1011}
{'process_name': 'P4', 'arrival_time': 23, 'burst_time': 105, 'waiting_time': 1745, 'time_to_burst': 0, 'completion_time': 1878}
{'process_name': 'P5', 'arrival_time': 36, 'burst_time': 107, 'waiting_time': 1918, 'time_to_burst': 0, 'completion_time': 2067}
{'process_name': 'P6', 'arrival_time': 38, 'burst_time': 125, 'waiting_time': 1763, 'time_to_burst': 0, 'completion_time': 1931}
{'process_name': 'P7', 'arrival_time': 49, 'burst_time': 117, 'waiting_time': 1914, 'time_to_burst': 0, 'completion_time': 2085}
{'process_name': 'P8', 'arrival_time': 56, 'burst_time': 86, 'waiting_time': 1544, 'time_to_burst': 0, 'completion_time': 1690}
{'process_name': 'P9', 'arrival_time': 62, 'burst_time': 119, 'waiting_time': 1944, 'time_to_burst': 0, 'completion_time': 2132}
{'process_name': 'P10', 'arrival_time': 71, 'burst_time': 90, 'waiting_time': 1545, 'time_to_burst': 0, 'completion_time': 1710}
{'process_name': 'P11', 'arrival_time': 74, 'burst_time': 89, 'waiting_time': 1794, 'time_to_burst': 0, 'completion_time': 1962}
{'process_name': 'P12', 'arrival_time': 87, 'burst_time': 107, 'waiting_time': 1898, 'time_to_burst': 0, 'completion_time': 2098}
{'process_name': 'P13', 'arrival_time': 90, 'burst_time': 124, 'waiting_time': 1790, 'time_to_burst': 0, 'completion_time': 2009}
{'process_name': 'P14', 'arrival_time': 94, 'burst_time': 106, 'waiting_time': 1898, 'time_to_burst': 0, 'completion_time': 2104}
{'process_name': 'P15', 'arrival_time': 108, 'burst_time': 112, 'waiting_time': 1889, 'time_to_burst': 0, 'completion_time': 2115}
{'process_name': 'P16', 'arrival_time': 119, 'burst_time': 121, 'waiting_time': 1814, 'time_to_burst': 0, 'completion_time': 2059}
{'process_name': 'P17', 'arrival_time': 124, 'burst_time': 95, 'waiting_time': 1649, 'time_to_burst': 0, 'completion_time': 1872}
{'process_name': 'P18', 'arrival_time': 138, 'burst_time': 99, 'waiting_time': 1905, 'time_to_burst': 0, 'completion_time': 2148}
{'process_name': 'P19', 'arrival_time': 143, 'burst_time': 70, 'waiting_time': 1367, 'time_to_burst': 0, 'completion_time': 1583}


q = 50
{'process_name': 'P0', 'arrival_time': 0, 'burst_time': 111, 'waiting_time': 1126, 'time_to_burst': 0, 'completion_time': 1239}
{'process_name': 'P1', 'arrival_time': 5, 'burst_time': 90, 'waiting_time': 708, 'time_to_burst': 0, 'completion_time': 805}
{'process_name': 'P2', 'arrival_time': 7, 'burst_time': 94, 'waiting_time': 1013, 'time_to_burst': 0, 'completion_time': 1116}
{'process_name': 'P3', 'arrival_time': 17, 'burst_time': 82, 'waiting_time': 1818, 'time_to_burst': 0, 'completion_time': 1921}
{'process_name': 'P4', 'arrival_time': 31, 'burst_time': 93, 'waiting_time': 1041, 'time_to_burst': 0, 'completion_time': 1167}
{'process_name': 'P5', 'arrival_time': 41, 'burst_time': 75, 'waiting_time': 1591, 'time_to_burst': 0, 'completion_time': 1710}
{'process_name': 'P6', 'arrival_time': 48, 'burst_time': 92, 'waiting_time': 1076, 'time_to_burst': 0, 'completion_time': 1218}
{'process_name': 'P7', 'arrival_time': 49, 'burst_time': 119, 'waiting_time': 1779, 'time_to_burst': 0, 'completion_time': 1951}
{'process_name': 'P8', 'arrival_time': 62, 'burst_time': 114, 'waiting_time': 1590, 'time_to_burst': 0, 'completion_time': 1769}
{'process_name': 'P9', 'arrival_time': 64, 'burst_time': 98, 'waiting_time': 1164, 'time_to_burst': 0, 'completion_time': 1328}
{'process_name': 'P10', 'arrival_time': 74, 'burst_time': 87, 'waiting_time': 1816, 'time_to_burst': 0, 'completion_time': 1982}
{'process_name': 'P11', 'arrival_time': 78, 'burst_time': 91, 'waiting_time': 1202, 'time_to_burst': 0, 'completion_time': 1373}
{'process_name': 'P12', 'arrival_time': 85, 'burst_time': 104, 'waiting_time': 1649, 'time_to_burst': 0, 'completion_time': 1841}
{'process_name': 'P13', 'arrival_time': 87, 'burst_time': 106, 'waiting_time': 1759, 'time_to_burst': 0, 'completion_time': 1956}
{'process_name': 'P14', 'arrival_time': 102, 'burst_time': 79, 'waiting_time': 1683, 'time_to_burst': 0, 'completion_time': 1867}
{'process_name': 'P15', 'arrival_time': 112, 'burst_time': 105, 'waiting_time': 1653, 'time_to_burst': 0, 'completion_time': 1873}
{'process_name': 'P16', 'arrival_time': 123, 'burst_time': 71, 'waiting_time': 1362, 'time_to_burst': 0, 'completion_time': 1558}
{'process_name': 'P17', 'arrival_time': 126, 'burst_time': 92, 'waiting_time': 1666, 'time_to_burst': 0, 'completion_time': 1887}
{'process_name': 'P18', 'arrival_time': 133, 'burst_time': 129, 'waiting_time': 1707, 'time_to_burst': 0, 'completion_time': 1973}
{'process_name': 'P19', 'arrival_time': 144, 'burst_time': 93, 'waiting_time': 1444, 'time_to_burst': 0, 'completion_time': 1683}

figure_1_timeseries_q10
figure_2_timeseries_q25
figure_3_timeseries_q50
figure_8_atats
figure_9_awts
figure_10_ncss

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment