计算机操作系统课实验

实现效果如下

from prettytable import PrettyTable
class PCB:
def __init__(self,ID,arrival,cputime):
self.ID=ID
self.prior=0
self.arrival=int(arrival)
self.cputime=int(cputime)
self.starttime=-1
self.endtime=0
self.zztime=0
self.dqzztime=0
self.remaining_time=int(self.cputime)
# 使用类来表示pcb
def FCFS(pcb):# 先来先服务算法
pcb.sort(key = lambda x:x.arrival,reverse=False)# 排序
for i in range(len(pcb)):
if(i==0):
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
elif(i>0 and int(pcb[i].arrival>pcb[i-1].endtime)):# 若下一个到达时间大于上一个结束时间
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
else:
pcb[i].starttime=pcb[i-1].endtime
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime# 计算结束时间
def SJF(pcb):# 短作业优先算法
pcb.sort(key = lambda x:x.arrival,reverse=False)# 排序
for i in range(len(pcb)):
if(i==0):
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
elif(i>0 and int(pcb[i].arrival>pcb[i-1].endtime)):
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
else:# 冒泡寻找已到达的最短时间pcb
tmp=pcb.copy()
MIN=i
for j in range(i+1,len(pcb)):
if int(tmp[j].arrival)<=int(pcb[i-1].endtime) and int(tmp[j].cputime)< int(tmp[MIN].cputime):
MIN=j
pcb[i],pcb[j]=pcb[j],pcb[i]
pcb[i].starttime=pcb[i-1].endtime
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
def PSA(pcb):# 优先算法
pcb.sort(key = lambda x:x.arrival,reverse=False)
for i in range(len(pcb)):
if(i==0):
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
elif(i>0 and int(pcb[i].arrival>pcb[i-1].endtime)):
pcb[i].starttime=pcb[i].arrival
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
else: # 寻找已到达的优先级最高pcb
tmp=pcb.copy()
MAX=i
for j in range(i+1,len(pcb)):
if int(tmp[j].arrival)<=int(pcb[i-1].endtime) and int(tmp[j].prior)>=int(tmp[MAX].prior):
MAX=j
pcb[i],pcb[j]=pcb[j],pcb[i]
pcb[i].starttime=pcb[i-1].endtime
pcb[i].endtime=pcb[i].starttime+pcb[i].cputime
def RR(pcb, time_slice):
time = 0 # 当前时间
queue = [p for p in sorted(pcb, key=lambda x: x.arrival)] # 按到达时间排序的队列
completed_processes = [] # 用于存储已完成的进程
while queue:
process = queue.pop(0)
# 处理进程的开始时间
if process.starttime == -1:
process.starttime = max(time, process.arrival) # 设置开始时间为当前时间或到达时间中较大的
# 执行时间为剩余时间或时间片(取最小值)
exec_time = min(process.remaining_time, time_slice)
time = process.starttime + exec_time
process.remaining_time -= exec_time
if process.remaining_time > 0: # 进程未完成
queue.append(process) # 进程重新放入队列等待下一轮
process.starttime = time # 设置为下次开始执行时间
else: # 进程完成
process.endtime = time
process.zztime = process.endtime - process.arrival
process.dqzztime = process.zztime / process.cputime
completed_processes.append(process)
# 更新原来的 pcb 列表,以便后续展示
pcb.clear()
pcb.extend(completed_processes)
pcb = []
def inPCB(): # 手动读入pcb
n=int(input("请输入进程数:"))
i=0
while(i<n):
ID=input("请输入进程ID:")
arrival,cputime=input("请输入进程到达时间,CPU时间:").split()
pcb.append(PCB(ID,arrival,cputime))
print(pcb[i].ID,pcb[i].arrival,pcb[i].cputime)
i = i + 1
def inFILE(): # 使用文件读入pcb
filename=input("输入文件名:")
try:
f=open(filename,"r")
except:
print("文件不存在")
return 0
data=f.read()
print(data)
data=data.split("\n")
for i in range(len(data)):
data[i]=data[i].split(" ")
for i in range(len(data)-1):
pcb.append(PCB(data[i][0],data[i][1],data[i][2]))
if data[i][3]:
pcb[i].prior=data[i][3]
def display():
szztime=0
sdqzztime=0
for i in range(len(pcb)):
pcb[i].zztime=float(pcb[i].endtime-pcb[i].arrival)
pcb[i].dqzztime=float(pcb[i].zztime/pcb[i].cputime)
szztime=szztime+pcb[i].zztime
sdqzztime=sdqzztime+pcb[i].dqzztime
azztime=float(szztime/len(pcb))
adqzztime=float(sdqzztime/len(pcb))
pcb.sort(key=lambda x:x.starttime,reverse=False)
resulttable=PrettyTable(["进程","到达时间","服务时间","开始时间","完成时间","周转时间","带权周转时间","优先级"])
for i in pcb:
resulttable.add_row([i.ID,i.arrival,i.cputime,i.starttime,i.endtime,i.zztime,i.dqzztime,i.prior])
print(resulttable)
print("平均周转时间为:%.2f"%azztime)
print("带权平均周转时间为:%.2f"%adqzztime)# 除了rr的统一计算
if __name__=='__main__':
print("1.先来先调度算法\n"
"2.短作业优先算法\n"
"3.优先算法\n"
"4.时间片轮转算法\n"
"请选择算法:")
choice=input()
if(choice=='1'):
inchoice=input("是否从文件读取数据?(y/n)")
if(inchoice=='y'):
inFILE()
else:
inPCB()
FCFS(pcb)
display()
elif(choice=='2'):
inchoice = input("是否从文件读取数据?(y/n)")
if (inchoice == 'y'):
inFILE()
else:
inPCB()
SJF(pcb)
display()
elif(choice=='3'):
inchoice = input("是否从文件读取数据?(y/n)")
if (inchoice == 'y'):
inFILE()
else:
inPCB()
PSA(pcb)
display()
elif(choice=='4'):
inchoice = input("是否从文件读取数据?(y/n)")
if (inchoice == 'y'):
inFILE()
else:
inPCB()
time_slice = int(input("请输入时间片:"))
RR(pcb, time_slice)
szztime = sum(p.zztime for p in pcb) # 总周转时间
sdqzztime = sum(p.dqzztime for p in pcb) # 总带权周转时间
azztime = szztime / len(pcb)
adqzztime = sdqzztime / len(pcb)
# 排序并打印
resulttable = PrettyTable(
["进程", "到达时间", "服务时间", "开始时间", "完成时间", "周转时间", "带权周转时间", "优先级"])
for p in pcb:
resulttable.add_row([p.ID, p.arrival, p.cputime, p.starttime, p.endtime, p.zztime, p.dqzztime, p.prior])
print(resulttable)
print("平均周转时间为:%.2f" % azztime)
print("带权平均周转时间为:%.2f" % adqzztime)
else:
print("输入错误")
exit()
输入数据格式
、
当然也可以手动输入
1266

被折叠的 条评论
为什么被折叠?



