如何在SimPy中实现一个进程完成后启动另一个进程?
问题描述
我正在完成一份作业,需要用SimPy实现一个包含两个步骤的算法,要求第一个步骤(procedure_1)执行完成后再启动第二个步骤(procedure_2)。
最初我在类的__init__方法里同时启动了两个进程,结果没法实现顺序执行;后来尝试在procedure_2里用env.timeout()等待,也没用,procedure_2每次迭代都会被中断。
之后按照建议在run()方法里尝试顺序创建并yield进程:
def run(self): print("------RUN1--------") self.procedure_1_proc = self.env.process(self.procedure_1()) yield self.env.process(self.procedure_1()) print("------RUN2--------") self.procedure_2_proc = self.env.process(self.procedure_2()) yield self.env.process(self.procedure_2())
但现在procedure_1能正常运行,procedure_2却启动不了。程序输出显示run()被多次调用,但执行到第一个yield后就不再推进,想知道原因和解决方法。
附初始代码:
import random import networkx as nx from distsim import * import matplotlib.pyplot as plt class Alg1(Node): def __init__(self,*args): Node.__init__(self, *args) self.dist = 0 self.dists = {} self.all_dists = {} self.time_stamp_one = 0 self.vel = 10 self.procedure_1_proc = self.env.process(self.procedure_1()) self.procedure_2_proc = self.env.process(self.procedure_2()) def procedure_1(self): # 这里是procedure_1的操作逻辑 # 必须先执行完,不能被中断 def procedure_2(self): # 这里是procedure_2的操作逻辑 # 要在procedure_1完成后再执行
程序输出:
------RUN1-------- ------RUN1-------- ------RUN1-------- ------RUN1-------- ----------PROCEDURE1-------------- 0: TIMEOUT received from 0 at time 2 ----------PROCEDURE1-------------- 0: TIMEOUT received from 0 at time 2 ----------PROCEDURE1-------------- 1: PROBE received from 0 at time 3 {0: 10.0} ----------PROCEDURE1-------------- 1: PROBE received from 0 at time 3 ----------PROCEDURE1-------------- 0: REPLY received from 1 at time 4 {1: 10.0} ----------PROCEDURE1-------------- 0: PROBE received from 1 at time 4 ----------PROCEDURE1-------------- 2: PROBE received from 1 at time 4 {1: 10.0} ----------PROCEDURE1-------------- 1: REPLY received from 2 at time 5 {0: 10.0, 2: 10.0} ----------PROCEDURE1-------------- 1: PROBE received from 2 at time 5 ----------PROCEDURE1-------------- 3: PROBE received from 2 at time 5 {2: 10.0} ----------PROCEDURE1-------------- 2: REPLY received from 3 at time 6 {1: 10.0, 3: 10.0} ----------PROCEDURE1-------------- 2: PROBE received from 3 at time 6
原因分析
- 重复启动procedure_1:在
run()里先创建了self.procedure_1_proc = self.env.process(self.procedure_1()),接着又yield self.env.process(self.procedure_1()),等于启动了两个独立的procedure_1进程,yield等待的是第二个实例,但第一个实例可能一直在运行,占用事件循环,导致run()无法继续推进。 - __init__里的进程启动未移除:原
__init__中启动两个进程的代码没删掉,这会导致在run()执行前,两个进程就已提前启动,直接打乱了顺序执行的逻辑。 - procedure_1无明确终止条件:如果
procedure_1是无限循环或者没有明确的退出逻辑,yield会一直等待它结束,自然不会执行后续的procedure_2代码。
解决方法
- 删除__init__里的进程启动代码:只保留变量初始化,移除启动
procedure_1和procedure_2的两行代码。 - 避免重复启动进程:在
run()中仅创建一次procedure_1进程,直接yield该进程实例即可,无需重复调用self.env.process()。 - 给procedure_1添加明确终止逻辑:检查
procedure_1的业务逻辑,确保完成任务后能正常退出,比如添加条件判断终止循环,或在末尾yield一个空超时事件来结束进程。
修正后的代码示例
import random import networkx as nx from distsim import * import matplotlib.pyplot as plt class Alg1(Node): def __init__(self,*args): Node.__init__(self, *args) self.dist = 0 self.dists = {} self.all_dists = {} self.time_stamp_one = 0 self.vel = 10 # 移除__init__里的进程启动代码 def run(self): print("------RUN1--------") # 仅创建一次procedure_1进程并等待其完成 self.procedure_1_proc = self.env.process(self.procedure_1()) yield self.procedure_1_proc print("------RUN2--------") # 启动procedure_2并等待其完成 self.procedure_2_proc = self.env.process(self.procedure_2()) yield self.procedure_2_proc def procedure_1(self): # 原有procedure_1操作逻辑 print("----------PROCEDURE1--------------") # 示例终止逻辑:完成所有操作后添加空超时事件确保进程正常结束 # 实际需根据业务逻辑添加合适的终止条件 yield self.env.timeout(0) def procedure_2(self): # 原有procedure_2操作逻辑 print("----------PROCEDURE2--------------") # 同样添加终止逻辑 yield self.env.timeout(0)
内容的提问来源于stack exchange,提问作者Alp Yıldırım
相关产品推荐
相关产品推荐

