先来先服务FCFS和短作业优先SJF进程调度算法
目录
一、环境
编译软件:pycharm
程序语言:python
二、问题描述:
设计程序模拟进程的先来先服务FCFS和短作业优先SJF调度过程。假设有n个进程分别在T1, … ,Tn时刻到达系统,它们需要的服务时间分别为S1, … ,Sn。分别采用先来先服务FCFS和短作业优先SJF进程调度算法进行调度,计算每个进程的完成时间、周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。
三、程序要求:
1)进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;选择算法1-FCFS,2-SJF。
2)要求采用先来先服务FCFS和短作业优先SJF分别调度进程运行,计算每个进程的周转时间和带权周转时间,并且计算所有进程的平均周转时间和带权平均周转时间;
3)输出:要求模拟整个调度过程,输出每个时刻的进程运行状态,如“时刻3:进程B开始运行”等等;
4)输出:要求输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。
四、实现提示:
1)参考用Process类:
class Process:
def __init__(self, name,arrival_time, service_time):
self.name = name
self.arrival_time = arrival_time #到达时间
self.service_time = service_time #服务时间
self.completion_time = 0 #完成时间
self.turnaround_time = 0 #周转时间
self.weighted_turnaround_time = 0 #带权周转时间
2)进程调度的实现过程如下:
- 变量初始化;
- 接收用户输入n,T1, … ,Tn,S1, … ,Sn;算法选择1-FCFS,2-SJF;
- 按照选择算法进行进程调度,计算进程的完成时间、周转时间和带权周转时间;
- 计算所有进程的平均周转时间和平均带权周转时间;
- 按格式输出调度结果。
五、代码设计与实现
(1)FCFS算法
设计思想:
1.定义一个进程的类,包括进程到达时间、服务时间、完成时间、周转时间、带权周转时间;以及初始化变量当前时间、平均周转时间和平均带权周转时间;
2.以进程的到达时间由早到晚进行排序;当前时间等于第一个进程到达的时间。比较前一个进程的完成时间和下一个进程的到达时间,而执行下一个进程时,需要判断该进程是否到达,若已到达,则当前时间等于前一个进程的完成时间,若未到达,则当前时间为该进程的到达时间。
3.刷新当前时间为进程的到达时间;完成时间=到达时间+服务时间;周转时间=完成时间-到达时间;带权周转时间=周转时间/服务时间;随着进程的执行更新以上变量。
4.执行进程,输入每个进程的到达时间按及服务时间,输出进程的到达时间、服务时间、完成 时间、周转时间、带权周转时间以及所有进程执行完后的平均周转时间和平均带权周转时间。
部分代码:
def fcfs(processes):
n = len(processes)
current_time = 0
for i in range(n):
process = processes[i]
if current_time < process.arrival_time:
current_time = process.arrival_time
process.completion_time = current_time + process.service_time
process.turnaround_time = process.completion_time - process.arrival_time
process.weighted_turnaround_time = process.turnaround_time / process.service_time
current_time = process.completion_time #当前时间为该进程的完成时间,继续执行下一个进程
(2)SJF算法
设计思想:
1.定义一个进程的类,包括进程到达时间、服务时间、完成时间、周转时间、带权周转时间;以及初始化变量当前时间、平均周转时间和平均带权周转时间;
2.先执行第一个到达的进程,当多个进程均到达且未执行时,比较进程的服务时间,服务时间较短的优先执行。继续执行下面的进程。
3.刷新当前时间为进程的到达时间;完成时间=到达时间+服务时间;周转时间=完成时间-到达时间;带权周转时间=周转时间/服务时间;随着进程的执行更新以上变量。
4.执行进程,输入每个进程的到达时间按及服务时间,输出进程的到达时间、服务时间、完成时间、周转时间、带权周转时间以及所有进程执行完后的平均周转时间和平均带权周转时间。
部分代码:
def sjf(processes):
n = len(processes)
current_time = 0
total_processes = len(processes)
completed_processes = 0 # 已完成进程数量
while completed_processes < total_processes:
shortest_process = None#初始化最短的进程
shortest_time = float('inf')
for process in processes:
#当前进程已到达且未被调用,在已到达进程中选择服务时间最短的进程执行
if process.arrival_time <= current_time and process.completion_time == 0:
if process.service_time < shortest_time:
shortest_process = process
shortest_time = process.service_time
#如果找到最短进程则执行,未找到最短进程则继续执行下一个到达的进程
if shortest_process:
shortest_process.completion_time = current_time + shortest_process.service_time
shortest_process.turnaround_time = shortest_process.completion_time - shortest_process.arrival_time
shortest_process.weighted_turnaround_time = shortest_process.turnaround_time / shortest_process.service_time
completed_processes += 1
current_time = shortest_process.completion_time
else:
current_time += 1
(3)完整代码
定义一个类(Process类),四个函数(fcfs(processes)、sjf(processes)、calculate()、update_table())。调用tkinker库来制作一个交互式图形页面。
import tkinter as tk
from tkinter import ttk
class Process:
def __init__(self, arrival_time, service_time):
self.arrival_time = arrival_time #到达时间
self.service_time = service_time #服务时间
self.completion_time = 0 #完成时间
self.turnaround_time = 0 #周转时间
self.weighted_turnaround_time = 0 #带权周转时间
def fcfs(processes):
n = len(processes)
current_time = 0
for i in range(n):
process = processes[i]
if current_time < process.arrival_time:
current_time = process.arrival_time
process.completion_time = current_time + process.service_time
process.turnaround_time = process.completion_time - process.arrival_time
process.weighted_turnaround_time = process.turnaround_time / process.service_time
current_time = process.completion_time #当前时间为该进程的完成时间,继续执行下一个进程
def sjf(processes):
n = len(processes)
current_time = 0
total_processes = len(processes)
completed_processes = 0 # 已完成进程数量
while completed_processes < total_processes:
shortest_process = None#初始化最短的进程
shortest_time = float('inf')
for process in processes:
#当前进程已到达且未被调用,在已到达进程中选择服务时间最短的进程执行
if process.arrival_time <= current_time and process.completion_time == 0:
if process.service_time < shortest_time:
shortest_process = process
shortest_time = process.service_time
#如果找到最短进程则执行,未找到最短进程则继续执行下一个到达的进程
if shortest_process:
shortest_process.completion_time = current_time + shortest_process.service_time
shortest_process.turnaround_time = shortest_process.completion_time - shortest_process.arrival_time
shortest_process.weighted_turnaround_time = shortest_process.turnaround_time / shortest_process.service_time
completed_processes += 1
current_time = shortest_process.completion_time
else:
current_time += 1
#从输入框获取数据,调用算法计算完成时间,周转时间,带权周转时间,计算进程的平均周转时间,平均带权周转时间
def calculate():
processes = []
for i in range(n):
arrival_time = int(arrival_entries[i].get())
service_time = int(service_entries[i].get())
processes.append(Process(arrival_time, service_time))
fcfs(processes)
# sjf(processes)
for i in range(n):
process = processes[i]
completion_labels[i].configure(text=process.completion_time)
turnaround_labels[i].configure(text=process.turnaround_time)
weighted_turnaround_labels[i].configure(text=process.weighted_turnaround_time)
total_turnaround_time = sum(process.turnaround_time for process in processes)
total_weighted_turnaround_time = sum(process.weighted_turnaround_time for process in processes)
avg_turnaround_time = total_turnaround_time / n
avg_weighted_turnaround_time = total_weighted_turnaround_time / n
avg_turnaround_label.configure(text=f"avg_turnaround_time:{avg_turnaround_time}")
avg_weighted_turnaround_label.configure(text=f"avg_weighted_turnaround_time:{avg_weighted_turnaround_time}")
# 创建GUI
window = tk.Tk()
window.title("FCFS Process Scheduling")
window.geometry("400x300")
n_label = tk.Label(window, text="Number of Processes:")
n_label.pack()
n_entry = tk.Entry(window)
n_entry.pack()
#调用caclulate函数
submit_button = tk.Button(window, text="Submit", command=calculate)
submit_button.pack()
table_frame = tk.Frame(window)
table_frame.pack()
# 制作表格
header_labels = ["Process", "Arrival Time", "Service Time", "Completion Time", "Turnaround Time", "Weighted Turnaround Time"]
for i in range(len(header_labels)):
header_label = ttk.Label(table_frame, text=header_labels[i], font=("bold"))
header_label.grid(row=0, column=i, padx=5, pady=5)
arrival_entries = []
service_entries = []
completion_labels = []
turnaround_labels = []
weighted_turnaround_labels = []
n = 0
#制作表格,刷新表格数据
def update_table():
global n
n = int(n_entry.get())
for widget in table_frame.winfo_children():
widget.destroy()
# Table headers
for i in range(len(header_labels)):
header_label = ttk.Label(table_frame, text=header_labels[i], font=("bold"))
header_label.grid(row=0, column=i, padx=5, pady=5)
arrival_entries.clear()
service_entries.clear()
completion_labels.clear()
turnaround_labels.clear()
weighted_turnaround_labels.clear()
for i in range(n):
process_label = ttk.Label(table_frame, text=f"Process {i+1}")
process_label.grid(row=i+1, column=0, padx=5, pady=5)
arrival_entry = ttk.Entry(table_frame)
arrival_entry.grid(row=i+1, column=1, padx=5, pady=5)
arrival_entries.append(arrival_entry)
service_entry = ttk.Entry(table_frame)
service_entry.grid(row=i+1, column=2, padx=5, pady=5)
service_entries.append(service_entry)
completion_label = ttk.Label(table_frame, text="")
completion_label.grid(row=i+1, column=3, padx=5, pady=5)
completion_labels.append(completion_label)
turnaround_label = ttk.Label(table_frame, text="")
turnaround_label.grid(row=i+1, column=4, padx=5, pady=5)
turnaround_labels.append(turnaround_label)
weighted_turnaround_label = ttk.Label(table_frame, text="")
weighted_turnaround_label.grid(row=i+1, column=5, padx=5, pady=5)
weighted_turnaround_labels.append(weighted_turnaround_label)
update_button = tk.Button(window, text="Update", command=update_table)
update_button.pack()
avg_turnaround_label = ttk.Label(window, text="")
avg_turnaround_label.pack()
avg_weighted_turnaround_label = ttk.Label(window, text="")
avg_weighted_turnaround_label.pack()
window.mainloop()