当前位置:   article > 正文

先来先服务调度算法、短作业优先调度算法、时间片轮转调度算法和优先级调度算法的实现(python)_进程调度短作业优先算法的实现

进程调度短作业优先算法的实现

一、算法简介:

  1. 先来先服务算法(FCFS):系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”;

  2. 短作业优先调度算法(SJF):以作业的长短来计算优先级,作业越短,其优先级越高。作业的长短是以作业所要求的运行时间来衡量的。;
  3. 时间片轮转调度算法(RR):每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾;
  4. 优先级调度算法(HRRN):优先级进程调度算法,是为每个作业设置一个优先权(响应比),然后把处理机分配给就绪队列中优先级最高的进程,在这里我们使用的是动态优先级,即在每次调度之前计算每个进程的优先级:RR(优先级) = 作业周转时间/作业运行时间 = 1 + 作业等待时间/作业运行时间。

     大概流程:

代码分两个:text_JCB.py,相当于一个main文件;text_JCB_function.py,写函数。

二、代码实现

  1. import text_JCB_function
  2. while(True):
  3. text_JCB_function.show_menu()
  4. action_str = input("请输入要选择的操作:")
  5. # 123 表示对进程的操作
  6. if action_str in ["1", "2", "3"]:
  7. if action_str == "1":
  8. # 新增一个进程
  9. text_JCB_function.new_JCB()
  10. continue
  11. elif action_str == "2":
  12. # 打印所有进程
  13. text_JCB_function.show_JCB()
  14. continue
  15. else:
  16. # 选择进程调度算法
  17. text_JCB_function.function_choice_menu()
  18. function_choice = input("请输入要选择的调度算法:")
  19. if function_choice in ["1", "2", "3", "4"]:
  20. if function_choice == "1":
  21. # 使用的是 先到先服务算法
  22. text_JCB_function.function_FCFS()
  23. continue
  24. if function_choice == '2':
  25. # 使用的是 短作业优先算法
  26. text_JCB_function.function_SJF()
  27. continue
  28. if function_choice == '3':
  29. # 使用时间片轮转调度算法,时间片为1
  30. text_JCB_function.function_RR()
  31. continue
  32. if function_choice == '4':
  33. # 使用 非抢占式优先级调度算法
  34. text_JCB_function.function_HRRN()
  35. continue
  36. continue
  37. # 0 表示退出系统
  38. elif action_str == "0":
  39. print("已退出,欢迎下次使用!!")
  40. break
  41. else:
  42. print("输入错误,请重新输入!")

  1. # 数据结构的确定 : 每个进程信息用字典存储,再用列表存储各个进程
  2. JCB_list = []
  3. # 进程模拟系统的 实际函数编写
  4. def show_menu():
  5. # 功能菜单:
  6. print("~" * 50)
  7. print("欢迎使用【进程调度算法展示系统】 [V 1.0]")
  8. print("1. 新增进程;\n2. 打印所有进程;\n3. 选择使用的进程调度算法;\n\n0. 退出系统;")
  9. print("~" * 50)
  10. def new_JCB():
  11. # 新增进程信息
  12. print("-" * 50)
  13. # > 1 提示用户输入进程相关信息
  14. while True:
  15. JCB_name = input("请输入进程名:")
  16. if JCB_name != "":
  17. break
  18. else:
  19. print("输入不能为空!")
  20. while True:
  21. JCB_come = input("请输入进程到达时间:")
  22. if JCB_name != "":
  23. break
  24. else:
  25. print("输入不能为空!")
  26. while True:
  27. JCB_need = input("请输入进程服务时间:")
  28. if JCB_name != "":
  29. break
  30. else:
  31. print("输入不能为空!")
  32. JCB_level = 0 # 将进程的优先级初始化为0
  33. # > 2 将进程信息存储在字典中
  34. JCB_dict = {
  35. "JCB_name" : JCB_name,
  36. "JCB_come" : JCB_come,
  37. "JCB_need" : JCB_need,
  38. 'JCB_level': JCB_level,
  39. }
  40. # > 3 将进程字典存储到列表中
  41. JCB_list.append(JCB_dict)
  42. # > 4 提示用户,新建进程成功
  43. print("新增进程名: %s 成功" % JCB_name)
  44. def show_JCB():
  45. # 显示所有的进程
  46. print("-" * 50)
  47. if len(JCB_list) == 0:
  48. print("当前没有任何进程,请先添加新的进程!")
  49. return
  50. # > 1 将JCB_list中的所有进程输出,遍历所有的list即可
  51. # 打印数据
  52. for jcb in JCB_list:
  53. print("进程名称:%s 到达时间:%s 服务时间:%s" % (jcb["JCB_name"], jcb["JCB_come"], jcb["JCB_need"]))
  54. # > 2 提示用户,显示所有进程成功
  55. print("进程输出完成!")
  56. def function_choice_menu():
  57. # 选择算法的界面
  58. print("~" * 50)
  59. print("【进程调度算法展示系统】 [V 1.0]\n")
  60. print("请选择要使用的调度算法:\n1. 先来先服务算法;\n2. 短作业优先算法;\n3. 时间片轮转调度算法;\n4. 优先调度算法;\n")
  61. print("~" * 50)
  62. def function_FCFS():
  63. # ***先到先服务算法:
  64. # 使用冒泡排序,将列表重新排序,按照 到达时间从小到大 排列
  65. time_going = 0.0 # 时间标识
  66. time = 0.0 # 作业周转时间的总和
  67. over_time = 0.0 # 每个作业的周转时间
  68. weighted_time = 0.0 # 作业的带权周转时间
  69. account_max = len(JCB_list)
  70. account = 0
  71. for i in range( len(JCB_list) - 1 ): # 将列表重新排序,按照进程到来的先后顺序
  72. for j in range( len(JCB_list) - i - 1 ):
  73. if JCB_list[j]["JCB_come"] > JCB_list[j + 1]["JCB_come"]:
  74. JCB_list[j], JCB_list[j + 1] = JCB_list[j + 1], JCB_list[j]
  75. while True: # 主体
  76. for jcb in JCB_list:
  77. if (float(jcb["JCB_come"]) <= time_going):
  78. time_going = time_going + float(jcb["JCB_need"])
  79. over_time = float(over_time) + float(jcb["JCB_need"]) - float(jcb["JCB_come"])
  80. time = float(time) + float(over_time)
  81. weighted_time = float(weighted_time) + over_time / float(jcb["JCB_need"])
  82. print("进程名称:%s 到达时间:%s 服务时间:%s 结束时间:%s" %
  83. (jcb["JCB_name"], jcb["JCB_come"], jcb["JCB_need"], over_time))
  84. # 执行过的作业,直接删除
  85. JCB_list.remove(jcb)
  86. account = account + 1
  87. break
  88. if account == account_max:
  89. break
  90. print("平均周转时间:%s 平均带权周转时间:%s" % (time/account_max, weighted_time/account_max))
  91. print("进程执行完毕!")
  92. def function_SJF():
  93. # ***短作业优先算法
  94. time = 0.0 # 作业周转时间的总和
  95. over_time = 0.0 # 每个作业的结束时间
  96. weighted_time = 0.0 # 作业的带权周转时间
  97. account = 0
  98. process_list = JCB_list
  99. account_max = len(process_list)
  100. for i in range( len(process_list) - 1 ):
  101. for j in range( len(process_list) - i - 1 ):
  102. if float(process_list[j]["JCB_need"]) > float(process_list[j + 1]["JCB_need"]):
  103. process_list[j], process_list[j + 1] = process_list[j + 1], process_list[j]
  104. while True: # 循环主体
  105. for i in range( len(process_list) ):
  106. if float(process_list[i]["JCB_come"]) <= over_time: # 判断进程是否到达
  107. over_time = float(over_time) + float(process_list[i]["JCB_need"])
  108. time = float(time) + float(over_time) - float(process_list[i]["JCB_come"])
  109. weighted_time = float(weighted_time) + (over_time - float(process_list[i]["JCB_come"])) / float(process_list[i]["JCB_need"])
  110. print("进程名称:%s 到达时间:%s 服务时间:%s 结束时间:%s" %
  111. (process_list[i]["JCB_name"], process_list[i]["JCB_come"], process_list[i]["JCB_need"], over_time))
  112. # 执行过的作业,直接删除
  113. account = account + 1
  114. process_list.remove(process_list[i])
  115. break
  116. if account == account_max:
  117. break
  118. print("平均周转时间:%s\t平均带权周转时间:%s" % (time/account_max, weighted_time/account_max))
  119. print("进程执行完毕!")
  120. def function_RR():
  121. # 按时间片轮转调度算法
  122. process_list = []# 用来表示进程的队列
  123. copy_list = JCB_list
  124. account_max = len(JCB_list) # 计数器,标识调度完成
  125. q = 1.0 # 时间片为1
  126. index = 0
  127. in_put = 0
  128. time_going = 0.0 # 时间进度
  129. time = 0.0 # 作业周转时间的总和
  130. nochange_list = []
  131. weighted_time = 0.0 # 作业的带权周转时间总和
  132. for k in JCB_list: # 首先将每个进程的服务时间保存下来,因为后续会对 JCB_need 不断进行修改
  133. nochange_list.append(k["JCB_need"])
  134. # 冒泡排序,按到达时间,从小到大排列
  135. for i in range( len(JCB_list) - 1 ):
  136. for j in range( len(JCB_list) - i - 1 ):
  137. if float(JCB_list[j]["JCB_come"]) > float(JCB_list[j + 1]["JCB_come"]):
  138. JCB_list[j], JCB_list[j + 1] = JCB_list[j + 1], JCB_list[j]
  139. while True: # 将第 0s已经就绪的进程,放入队列
  140. if index == len(copy_list):
  141. break
  142. if float((copy_list[index]["JCB_come"])) <= time_going:
  143. process_list.append(copy_list[index])
  144. copy_list.remove(copy_list[index])
  145. index -= 1
  146. index += 1
  147. while True:
  148. # 调度循环
  149. if len(process_list) == 0: # 进程列表为空,退出循环
  150. break
  151. current_process = process_list[0]
  152. process_list.remove(current_process) # 将即将要工作的作业,从列表去除,待操作完如果need > 0,再写回
  153. if float(current_process["JCB_need"]) > 0: # 还没有循环完毕
  154. if float(current_process["JCB_need"]) >= q: # 还没有循环完毕,并且这一个进程需要的时间大于时间片
  155. time_going += q
  156. current_process["JCB_need"] = float(current_process["JCB_need"]) - q
  157. else: # 需要的时间小于时间片
  158. time_going = time_going + float(current_process["JCB_need"])
  159. current_process["JCB_need"] = 0
  160. if float(current_process["JCB_need"]) == 0: # 已经循环完毕,计算平均周转时间,平均带权周转时间
  161. time = time + time_going - float(current_process["JCB_come"]) # 累加周转时间 and 加权周转时间
  162. for jcb_need in range(len(nochange_list)): # 取到已经结束的作业的 need, 并将该作业删除
  163. if jcb_need + 1 == float(current_process["JCB_name"]):
  164. need = float(nochange_list[jcb_need])
  165. break
  166. weighted_time = weighted_time + (time_going - float(current_process["JCB_come"])) / need
  167. print("进程名称:%s 到达时间:%s 结束时间:%s" %
  168. (current_process["JCB_name"], current_process["JCB_come"], time_going))
  169. while True:
  170. if in_put == len(copy_list):
  171. break
  172. if float((copy_list[in_put]["JCB_come"])) <= time_going:
  173. process_list.append(copy_list[in_put])
  174. copy_list.remove(copy_list[in_put])
  175. in_put -= 1 # 回退一行
  176. in_put += 1 # 向下执行
  177. in_put = 0 # 归零
  178. if current_process["JCB_need"] != 0: # 上一个作业,还没有执行完毕,将这个作业加到最后一个,待执行
  179. process_list.append(current_process)
  180. print("平均周转时间:%s 平均带权周转时间:%s" % (time/account_max, weighted_time/account_max))
  181. print("进程执行完毕!")
  182. def function_HRRN():
  183. # 按非抢占式优先级调度算法
  184. process_list = []
  185. time = 0.0 # 作业周转时间的总和
  186. over_time = 0.0 # 每个作业的结束时间
  187. weighted_time = 0.0 # 作业的带权周转时间
  188. index = 0
  189. in_put = 0
  190. copy_list = JCB_list
  191. account_max = len(copy_list)
  192. # 每次循环,都要重新查询进程的优先级
  193. while True: # 将已经就绪的进程,放入就绪队列,并从进程队列中删除
  194. if index == len(copy_list):
  195. break
  196. if float((copy_list[index]["JCB_come"])) <= over_time:
  197. process_list.append(copy_list[index])
  198. copy_list.remove(copy_list[index])
  199. index -= 1
  200. index += 1
  201. while True: # 循环主体
  202. if len(process_list) == 0: # 进程列表为空,退出循环
  203. break
  204. max_level = 0.0 # 进程不为空,循环进程列表,求出每一个进程 此刻对应的响应比,响应比高者,优先处理
  205. for item in process_list:
  206. item["JCB_level"] = 1 + over_time / float(item["JCB_need"]) # 计算某进程当前的响应比
  207. if item["JCB_level"] > max_level: # 响应比高者,优先调度
  208. max_level = item["JCB_level"]
  209. current_process = item # 拿到最高响应比的进程
  210. # 进行操作,依次计算
  211. over_time = float(over_time) + float(current_process["JCB_need"])
  212. time = float(time) + float(over_time) - float(current_process["JCB_come"])
  213. weighted_time = float(weighted_time) + (over_time - float(current_process["JCB_come"])) / float(current_process["JCB_need"])
  214. print("进程名称:%s 到达时间:%s 服务时间:%s 优先级:%s 结束时间:%s" %
  215. (current_process["JCB_name"], current_process["JCB_come"], current_process["JCB_need"], current_process["JCB_level"], over_time))
  216. # 执行过的作业,直接删除
  217. process_list.remove(current_process)
  218. while True: # 将已经就绪的进程,放入队列
  219. if in_put == len(copy_list):
  220. break
  221. if float((copy_list[in_put]["JCB_come"])) <= over_time:
  222. process_list.append(copy_list[in_put])
  223. copy_list.remove(copy_list[in_put])
  224. in_put -= 1
  225. in_put += 1
  226. in_put = 0
  227. print("平均周转时间:%s\t平均带权周转时间:%s" % (time / account_max, weighted_time / account_max))
  228. print("进程执行完毕!")

三、源码下载:

百度网盘:百度网盘

提取码:iuxp

 可能有错误,欢迎指出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/582387
推荐阅读
相关标签
  

闽ICP备14008679号