进程控制和调度算法实验

计算机操作系统课实验

实现效果如下

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()

输入数据格式

当然也可以手动输入

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值