操作系统——sjf算法实现

python源码:

# --*-- coding:utf-8 --*--
# python3.5
import time
pcb = []
# 列表保存进程

# 输入函数
def InPcb():
        # n 计数读取的行数
        n = 0
        print("读取的文本内容为......")
        with open("pcb.txt") as f:
            # 读取文件内容
            line = f.readline()
            while line:
                '''readline()逐行读取文本的所有内容,结果是一个字符串,使用L.rstrip('\n')去掉换行符'''
                line = line.rstrip('\n').split(' ')
                print(line)
                pName = line[0]
                arriveTime =int(line[1])
                serviceTime = int(line[2])
                pcb.append([pName, arriveTime, serviceTime, 0, 0, 0, 0])
                n += 1
                #  进程名,到达时间,服务时间,开始,完成,周转,带权周转
                line = f.readline()
        # print(pcb)
        return n
# 最短进程优先算法
def SJF():
    sjf_pcb = pcb
    i = 1
    k = 0
    # 对列表按照到达时间进行升序排序  x:x[1]为依照到达时间进行排序
    sjf_pcb.sort(key=lambda x: x[1], reverse=False)

    # 定义列表的第一项内容
    startTime0 = int(sjf_pcb[0][1])
    pcb[0][3] = startTime0
    # 开始时间
    pcb[0][4] = startTime0 + int(sjf_pcb[0][2])
    # 完成时间
    sjf_pcb[0][5] = int(sjf_pcb[0][4]) - int(sjf_pcb[0][1])
    # 周转时间
    sjf_pcb[0][6] = float(sjf_pcb[0][5]) / int(sjf_pcb[0][2])
    # 带权周转

    # 对后背队列按照服务时间排序
    temp_pcb = sjf_pcb[1:len(sjf_pcb)]  # 切片 临时存放后备队列  len(sjf_pcb)获取长度
    temp_pcb.sort(key=lambda x: x[2], reverse=False)
    # 将服务进程短的放在前面
    sjf_pcb[1:len(sjf_pcb)] = temp_pcb
    print("服务进程短优先排序为.....")
    print(sjf_pcb)
    """
    首先考虑当排序后的首个进程到达时间大于前一进程完成时间,用K值避免对最后一个进程的两次计算
    """
    while (i < n):
        h = 1
        # 比较到达时间和前一者的完成时间,判断是否需要进行重新排序
        while (int(sjf_pcb[i][1]) <= int(sjf_pcb[i - 1][4])):
            if (i == n - 1):  # 当最后一个进程的到达时间小于前一个进程的完成时间
                startTime = sjf_pcb[i][1]
                sjf_pcb[i][3] = startTime
                sjf_pcb[i][4] = startTime + int(sjf_pcb[i][2])
                sjf_pcb[i][5] = int(sjf_pcb[i][4]) - int(sjf_pcb[i][1])
                sjf_pcb[i][6] = float(sjf_pcb[i][5]) / int(sjf_pcb[i][2])
                k = 1  # 设置参数对比,避免一重循环之后再对末尾进程重新计算
                break
            else:  # 对进程顺序进行调换
                temp_sjf_pcb = sjf_pcb[i]
                sjf_pcb[i] = sjf_pcb[i + h]
                sjf_pcb[i + h] = temp_sjf_pcb
                h += 1

                """
                如果后面的所有进程的到达时间都大于第 i 个进程的完成时间
                则重新将i之后的进程按照服务时间排序,直接对其进行计算,同时i += 1,直接开始后面的计算              
                """
                if (h >= n - i - 1):
                    temp_pcb2 = sjf_pcb[i:len(sjf_pcb)]
                    temp_pcb2.sort(key=lambda x: x[1], reverse=False)  # 后续队列重新按照到达时间顺序进行排序
                    sjf_pcb[i:len(sjf_pcb)] = temp_pcb2

                    sjf_pcb[i][3] = int(sjf_pcb[i][1])
                    sjf_pcb[i][4] = int(sjf_pcb[i][1]) + int(sjf_pcb[i][2])
                    sjf_pcb[i][5] = int(sjf_pcb[i][4]) - int(sjf_pcb[i][1])
                    sjf_pcb[i][6] = float(sjf_pcb[i][5]) / int(sjf_pcb[i][2])

                    temp_pcb2 = sjf_pcb[i + 1:len(sjf_pcb)]
                    temp_pcb2.sort(key=lambda x: x[2], reverse=False)  # 重新按照服务时间排序
                    sjf_pcb[i + 1:len(sjf_pcb)] = temp_pcb2
                    h = 1
                    i += 1
                else:
                    continue
        if (k == 1):
            break
        else:
            startTime = sjf_pcb[i - 1][4]
            sjf_pcb[i][3] = startTime
            sjf_pcb[i][4] = startTime + int(sjf_pcb[i][2])
            sjf_pcb[i][5] = int(sjf_pcb[i][4]) - int(sjf_pcb[i][1])
            sjf_pcb[i][6] = float(sjf_pcb[i][5]) / int(sjf_pcb[i][2])

            i += 1
    # 计算平均周转时间和平均带权周转时间
    SzzTime = 0
    SdqzzTime = 0
    for i in range(n):
        SzzTime = float(SzzTime + float(pcb[i][5]))
        SdqzzTime = float(SdqzzTime + float(pcb[i][6]))
        AzzTime = float(SzzTime / n)
        AdqzzTime = float(SdqzzTime / n)
    # 输出结果,按照开始时间进行排序
    sjf_pcb.sort(key=lambda x: x[4], reverse=False)
    print("运行结果:")
    for i in range(n):
        for m in range(800):
            print("\r 进程已经完成: %.2f %%" % ((m + 1) * 100.0 / 800), end="")
            time.sleep(0.005)
        print("时刻: %d 开始运行进程: %s    完成时间: %d 周转时间: %d 带权周转时间: %.2f" \
              % (int(sjf_pcb[i][3]), sjf_pcb[i][0], int(sjf_pcb[i][4]), int(sjf_pcb[i][5]), float(sjf_pcb[i][6])))
        i += 1
    print("本次调度的平均周转时间为: %.2f" % float(AzzTime))
    print("本次调度的平均带权周转时间为: %.2f" % float(AdqzzTime))


# 运行过程
if __name__ == '__main__':
    n = InPcb()
    # print(n)
    print("最短进程优先算法SJF")
    m = 1
    while (m == 1):
        option = int(input("请输入1运行算法(其他键退出):"))
        if (option == 1):
            SJF()
        else:
            print("退出计算")
            m = 0

猜你喜欢

转载自blog.csdn.net/Growing_hacker/article/details/88983669