在 python 中,我如何 运行 并发生成器循环在其中一个产生时暂停或终止?
in python, how can i run concurrent generator loops that pause or terminate when one of them yields?
我想在一台生产设备上模拟维护过程。这台机器可能由于以下三个原因之一而停机维护,即 (i) 它可能根据 1/MTBF 的指数描述的指数分布概率发生故障,其中 MTBF 是平均故障间隔时间,(ii) 或者它可能最终会按照定义的时间表进行基于时间的服务,例如自上次服务以来的 4、13、26 或 52 周后,其服务会重新设置故障概率以重新开始 (iii) 或者它可能是拆除进行例行检查,并根据检查结果进行任何维修或修复工作,这将再次重置故障指数功能。是否可以设置三个 while True 循环,它们将同时 运行 它们各自的超时函数,但一旦三个进程中的任何一个实际超时,所有循环都会停止?最好在简单的环境中?像...
import simpy
import random
mtbf = 150 #hours
service_interval = 600 #hours
inspect_repair_interval = 300 #hours
def run_to_failure():
while True:
failed = random.expovariate(1/mtbf)
yield env.timeout(failed)
def run_to_service():
while True:
stopped = service_interval
yield env.timeout(stopped)
def run_to_repair():
while True:
paused = inspect_repair_interval
yield env.timeout(paused)
现在,我如何 运行 所有 3 个功能同时运行,但能够在其中任何一个产生时停止并重置所有功能?产生的值将作为后续过程的输入,这些后续过程中的哪一个 运行 也取决于哪个函数产生了值
这里是一个机器同时有三个进程运行的例子:主机任务,定期维护的循环,故障事件
"""
quick sim of a machine with breakdowns
programmer: Michael R. Gibbs
"""
import simpy
import random
class Machine():
"""
A machine with a main processing loop that can be
interupted with breakdowns
"""
def __init__(self, env):
"""
Initializes the machine and starts
processing and breadowns
"""
self.env = env
# start main task
self.startup()
# start schedule for service
self.service = self.env.process(self.wait_for_service())
def startup(self):
"""
Starts up the machine
Also starts up the breakdown schedule
"""
self.task = self.env.process(self.main_task())
self.breakdown = self.env.process(self.wait_for_breakdown())
def shut_down(self):
"""
Shuts down the machine
Also kills the pending breakdown
"""
if self.task is not None:
# only shutdown if not running
self.task.interrupt()
self.task = None
if self.breakdown is not None:
# only cancel pending breakdown if it is still pending
self.breakdown.interrupt()
def main_task(self):
"""
The main processing loop of the machine
"""
print(f'{self.env.now} - starting up machine')
try:
while True:
yield self.env.timeout(3)
print(f'{self.env.now} - did some work')
except simpy.Interrupt as i:
print(f'{self.env.now} - processing has been interupted')
print(f'{self.env.now} - shutting down machine')
def wait_for_service(self):
"""
Schedules and executes maintaince
runs on a loop
breakdowns do not delay maintenance schedule
"""
while True:
yield self.env.timeout(21)
# time for maintenance
print(f'{self.env.now} - time for service')
if self.task is None:
# already processing a breakdown
print( "-------already shutdown ")
else:
self.shut_down()
# do maintenance
yield self.env.timeout(2)
print(f'{self.env.now} - finished service')
# restart machaine
self.startup()
def wait_for_breakdown(self):
"""
Creates a one time breakdown
"""
print(f'{self.env.now} - breakdow clock started')
try:
yield self.env.timeout(random.randint(4,10))
# time for a breakdown
self.breakdown = None
print(f'{self.env.now} - breakdown')
# shutdown and fix machine
self.shut_down()
yield self.env.timeout(7)
# machine fixed, start it back up
print(f'{self.env.now} - breakdow fixed')
self.startup()
except simpy.Interrupt as i:
print(f'{self.env.now} - breakdow clock stopped')
env = simpy.Environment()
machine = Machine(env)
env.run(100)
我想在一台生产设备上模拟维护过程。这台机器可能由于以下三个原因之一而停机维护,即 (i) 它可能根据 1/MTBF 的指数描述的指数分布概率发生故障,其中 MTBF 是平均故障间隔时间,(ii) 或者它可能最终会按照定义的时间表进行基于时间的服务,例如自上次服务以来的 4、13、26 或 52 周后,其服务会重新设置故障概率以重新开始 (iii) 或者它可能是拆除进行例行检查,并根据检查结果进行任何维修或修复工作,这将再次重置故障指数功能。是否可以设置三个 while True 循环,它们将同时 运行 它们各自的超时函数,但一旦三个进程中的任何一个实际超时,所有循环都会停止?最好在简单的环境中?像...
import simpy
import random
mtbf = 150 #hours
service_interval = 600 #hours
inspect_repair_interval = 300 #hours
def run_to_failure():
while True:
failed = random.expovariate(1/mtbf)
yield env.timeout(failed)
def run_to_service():
while True:
stopped = service_interval
yield env.timeout(stopped)
def run_to_repair():
while True:
paused = inspect_repair_interval
yield env.timeout(paused)
现在,我如何 运行 所有 3 个功能同时运行,但能够在其中任何一个产生时停止并重置所有功能?产生的值将作为后续过程的输入,这些后续过程中的哪一个 运行 也取决于哪个函数产生了值
这里是一个机器同时有三个进程运行的例子:主机任务,定期维护的循环,故障事件
"""
quick sim of a machine with breakdowns
programmer: Michael R. Gibbs
"""
import simpy
import random
class Machine():
"""
A machine with a main processing loop that can be
interupted with breakdowns
"""
def __init__(self, env):
"""
Initializes the machine and starts
processing and breadowns
"""
self.env = env
# start main task
self.startup()
# start schedule for service
self.service = self.env.process(self.wait_for_service())
def startup(self):
"""
Starts up the machine
Also starts up the breakdown schedule
"""
self.task = self.env.process(self.main_task())
self.breakdown = self.env.process(self.wait_for_breakdown())
def shut_down(self):
"""
Shuts down the machine
Also kills the pending breakdown
"""
if self.task is not None:
# only shutdown if not running
self.task.interrupt()
self.task = None
if self.breakdown is not None:
# only cancel pending breakdown if it is still pending
self.breakdown.interrupt()
def main_task(self):
"""
The main processing loop of the machine
"""
print(f'{self.env.now} - starting up machine')
try:
while True:
yield self.env.timeout(3)
print(f'{self.env.now} - did some work')
except simpy.Interrupt as i:
print(f'{self.env.now} - processing has been interupted')
print(f'{self.env.now} - shutting down machine')
def wait_for_service(self):
"""
Schedules and executes maintaince
runs on a loop
breakdowns do not delay maintenance schedule
"""
while True:
yield self.env.timeout(21)
# time for maintenance
print(f'{self.env.now} - time for service')
if self.task is None:
# already processing a breakdown
print( "-------already shutdown ")
else:
self.shut_down()
# do maintenance
yield self.env.timeout(2)
print(f'{self.env.now} - finished service')
# restart machaine
self.startup()
def wait_for_breakdown(self):
"""
Creates a one time breakdown
"""
print(f'{self.env.now} - breakdow clock started')
try:
yield self.env.timeout(random.randint(4,10))
# time for a breakdown
self.breakdown = None
print(f'{self.env.now} - breakdown')
# shutdown and fix machine
self.shut_down()
yield self.env.timeout(7)
# machine fixed, start it back up
print(f'{self.env.now} - breakdow fixed')
self.startup()
except simpy.Interrupt as i:
print(f'{self.env.now} - breakdow clock stopped')
env = simpy.Environment()
machine = Machine(env)
env.run(100)