SimPy中while循环仅迭代首次启动作业及总执行时间计算问题
SimPy作业调度问题修复方案
问题1:前3个作业循环执行、第4个作业无法调度的修复
- 故障根因:
system函数中多余的while循环会导致作业执行完成释放资源后,再次满足循环条件重复提交,所以前3个作业会无限循环执行。- 提前判断
cluster.total_machines.level是否满足需求的逻辑错误:第4个作业初始化时剩余资源仅为1,不满足3的申请要求,循环条件直接不成立,进程直接退出,不会等待资源释放后再尝试申请。
- 修复逻辑:删除
while循环,直接调用cluster.total_machines.get()申请资源,SimPy的Container会自动在资源不足时阻塞当前进程,待资源足够时自动唤醒执行。
问题2:统计所有作业总执行时间的实现
- 实现逻辑:
- 给
Job类新增job_endtime属性,记录每个作业的完成时间,可用于计算单个作业的周转时间。 - 给
Cluster类新增已完成作业计数、总作业数、总结束时间属性,当已完成作业数等于总作业数时,记录当前仿真时间为所有作业的总结束时间,可直接作为总执行时间使用。
- 给
修复后完整代码
import simpy class Cluster: def __init__(self, env, total_jobs): self.total_machines = simpy.Container(env, init=6) self.total_jobs = total_jobs self.completed_jobs = 0 self.all_job_end_time = 0 # 所有作业执行完成的总时间 class Job: def __init__(self, env, job_id, job_arrivaltime, job_time, job_machine_req): self.env = env self.job_id = job_id self.job_arrivaltime = job_arrivaltime self.job_time = job_time self.job_machine_req = job_machine_req self.job_endtime = 0 # 单个作业的完成时间 def system(env, job, cluster): print("当前集群剩余资源", cluster.total_machines.level) print('%s 到达时间 %s' % (job.job_id, env.now)) # 资源不足时自动阻塞,不需要提前判断 yield cluster.total_machines.get(job.job_machine_req) print('%s 开始执行,申请资源数 %s,当前时间 %s' % (job.job_id, job.job_machine_req, env.now)) yield env.timeout(job.job_time) # 记录作业完成时间 job.job_endtime = env.now print('%s 执行完成,当前时间 %s' % (job.job_id, env.now)) yield cluster.total_machines.put(job.job_machine_req) # 更新完成计数 cluster.completed_jobs += 1 # 所有作业完成时记录总结束时间,主动停止仿真 if cluster.completed_jobs == cluster.total_jobs: cluster.all_job_end_time = env.now env.exit() # 仿真初始化 env = simpy.Environment() jobs = [ Job(env, '1', 0, 3, 2), Job(env, '2', 0, 2, 2), Job(env, '3', 0, 3, 1), Job(env, '4', 0, 4, 3), ] cluster = Cluster(env, len(jobs)) for job in jobs: env.process(system(env, job, cluster)) # 启动仿真,自动在所有作业完成后停止 env.run() # 统计结果输出 print("=====执行统计结果=====") print(f"所有作业总执行时长:{cluster.all_job_end_time} 单位时间") for job in jobs: print(f"作业{job.job_id} 周转时间:{job.job_endtime - job.job_arrivaltime} 单位时间")
执行结果说明
运行后可以看到第4个作业会在作业2执行完成(时间点2)释放资源后启动,所有作业总执行时长为6单位时间,所有作业的周转时间也会同步输出。
内容的提问来源于stack exchange,提问作者wasiq khan
相关产品推荐
相关产品推荐

