简单;如何合并未知数量的中断
Simpy; how to incorporate an unknown amount of interrupts
我正在使用 python 和 simpy 进行模拟。在模拟中,一个实例(中断)可以被另一个实例(中断器)中断。我对每个中断使用嵌套的 try except 语句。如果我知道最大中断次数,嵌套的 try except 语句就可以工作。
问题是我不知道会发生多少次中断(可能是 1,2,3, ...)。我不知道如何处理被打断次数未知的对象。
下面的代码适用于三个中断,但如果包含第四个中断(由于三个嵌套的 try except 语句),则会出现故障。
是否可以使代码更通用,以便它可以处理未知数量的中断?
非常感谢任何帮助。
代码:
import simpy
import random
class Interupted(object):
def __init__(self, env):
self.env = env
self.isInterrupted = False
self.action = env.process(self.run())
def run(self):
self.isInterrupted = False
try:
print('uninterrupted at %s' % (self.env.now))
yield self.env.timeout(3)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
try:
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
try:
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
class Interruptor(object):
def __init__(self, env, interrupted):
self.env = env
self.interrupted = interrupted
self.action = env.process(self.run(interrupted))
def run(self, interrupted):
yield self.env.timeout(1)
interrupted.action.interrupt("first interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("second interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("third interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("fourth interrupt")
env = simpy.Environment()
interrupted = Interupted(env)
interruptor = Interruptor(env, interrupted)
env.run(until=15)
输出:
uninterrupted at 0
first interrupt
interrupted at 1
second interrupt
interrupted at 2
third interrupt
interrupted at 3
Traceback (most recent call last):
File "interrupt.py", line 58, in <module>
env.run(until=15)
File "/usr/local/lib/python2.7/dist-packages/simpy/core.py", line 137, in run
self.step()
File "/usr/local/lib/python2.7/dist-packages/simpy/core.py", line 229, in step
raise exc
simpy.events.Interrupt: Interrupt('fourth interrupt')
使用的版本:
- Python: 2.7.3
- Simpy: 3.0.7
我取得了一些进展并提出了解决方案。
多重中断不需要嵌套的try except语句。单独的声明似乎也有效。经过一些尝试和错误后,我发现也可以使用单独的 try except 语句。
第一个中断启动一个计数器。每个中断都会增加计数器,而 while 循环确保处理所有中断。只要 except 不包含上述额外的 yield 语句,它就可以工作。
代码:
import simpy
import random
class Interupted(object):
def __init__(self, env):
self.env = env
self.isInterrupted = False
self.interruptions = 0
self.action = env.process(self.run())
def run(self):
print('start at time %s' % (self.env.now))
try:
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
self.isInterrupted = not self.isInterrupted
self.interruptions += 1
print('interrupted at time %s interrupted: %s interrupted by: %s' % (self.env.now, self.isInterrupted, interrupt.cause))
while (self.interruptions > 0):
self.interruptions = self.interruptions - 1
try:
yield self.env.timeout(5)
except simpy.Interrupt as interrupt:
self.interruptions += 1
print('interrupted at time %s interrupted: %s interrupted by: %s' % (self.env.now, self.isInterrupted, interrupt.cause))
print('end at time %s' % (self.env.now))
class Interruptor(object):
def __init__(self, env, interrupted):
self.env = env
self.interrupted = interrupted
self.action = env.process(self.run(interrupted))
def run(self, interrupted):
for i in range(16):
yield self.env.timeout(5)
if(not interrupted.action.processed):
interrupted.action.interrupt("interrupt nr: %s" % i)
env = simpy.Environment()
interrupted = Interupted(env)
interruptor = Interruptor(env, interrupted)
env.run(until=100)
感谢您的post,它对我们帮助很大。使用 while 循环的想法是必不可少的。我们已经调整了您的解决方案,以便产生一定时间的超时 - 不间断。最好 Simpy 会在 yield 语句中添加一个 uninterrupted 关键字。 (类似于:yield env.timeout(15) uninterrupted
)。
我们最终得到了这样的解决方案:
remaining_time = time_to_wait
while remaining_time > 0:
try:
start = env.now
yield env.timeout(remaining_time)
except simpy.Interupt:
pass
finally:
elapsed = env.now - start
remaining_time -= elapsed
我正在使用 python 和 simpy 进行模拟。在模拟中,一个实例(中断)可以被另一个实例(中断器)中断。我对每个中断使用嵌套的 try except 语句。如果我知道最大中断次数,嵌套的 try except 语句就可以工作。
问题是我不知道会发生多少次中断(可能是 1,2,3, ...)。我不知道如何处理被打断次数未知的对象。
下面的代码适用于三个中断,但如果包含第四个中断(由于三个嵌套的 try except 语句),则会出现故障。
是否可以使代码更通用,以便它可以处理未知数量的中断?
非常感谢任何帮助。
代码:
import simpy
import random
class Interupted(object):
def __init__(self, env):
self.env = env
self.isInterrupted = False
self.action = env.process(self.run())
def run(self):
self.isInterrupted = False
try:
print('uninterrupted at %s' % (self.env.now))
yield self.env.timeout(3)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
try:
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
try:
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
print(interrupt.cause)
self.isInterrupted = True
print('interrupted at %s' % (self.env.now))
yield self.env.timeout(10)
class Interruptor(object):
def __init__(self, env, interrupted):
self.env = env
self.interrupted = interrupted
self.action = env.process(self.run(interrupted))
def run(self, interrupted):
yield self.env.timeout(1)
interrupted.action.interrupt("first interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("second interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("third interrupt")
yield self.env.timeout(1)
interrupted.action.interrupt("fourth interrupt")
env = simpy.Environment()
interrupted = Interupted(env)
interruptor = Interruptor(env, interrupted)
env.run(until=15)
输出:
uninterrupted at 0
first interrupt
interrupted at 1
second interrupt
interrupted at 2
third interrupt
interrupted at 3
Traceback (most recent call last):
File "interrupt.py", line 58, in <module>
env.run(until=15)
File "/usr/local/lib/python2.7/dist-packages/simpy/core.py", line 137, in run
self.step()
File "/usr/local/lib/python2.7/dist-packages/simpy/core.py", line 229, in step
raise exc
simpy.events.Interrupt: Interrupt('fourth interrupt')
使用的版本:
- Python: 2.7.3
- Simpy: 3.0.7
我取得了一些进展并提出了解决方案。
多重中断不需要嵌套的try except语句。单独的声明似乎也有效。经过一些尝试和错误后,我发现也可以使用单独的 try except 语句。
第一个中断启动一个计数器。每个中断都会增加计数器,而 while 循环确保处理所有中断。只要 except 不包含上述额外的 yield 语句,它就可以工作。
代码:
import simpy
import random
class Interupted(object):
def __init__(self, env):
self.env = env
self.isInterrupted = False
self.interruptions = 0
self.action = env.process(self.run())
def run(self):
print('start at time %s' % (self.env.now))
try:
yield self.env.timeout(10)
except simpy.Interrupt as interrupt:
self.isInterrupted = not self.isInterrupted
self.interruptions += 1
print('interrupted at time %s interrupted: %s interrupted by: %s' % (self.env.now, self.isInterrupted, interrupt.cause))
while (self.interruptions > 0):
self.interruptions = self.interruptions - 1
try:
yield self.env.timeout(5)
except simpy.Interrupt as interrupt:
self.interruptions += 1
print('interrupted at time %s interrupted: %s interrupted by: %s' % (self.env.now, self.isInterrupted, interrupt.cause))
print('end at time %s' % (self.env.now))
class Interruptor(object):
def __init__(self, env, interrupted):
self.env = env
self.interrupted = interrupted
self.action = env.process(self.run(interrupted))
def run(self, interrupted):
for i in range(16):
yield self.env.timeout(5)
if(not interrupted.action.processed):
interrupted.action.interrupt("interrupt nr: %s" % i)
env = simpy.Environment()
interrupted = Interupted(env)
interruptor = Interruptor(env, interrupted)
env.run(until=100)
感谢您的post,它对我们帮助很大。使用 while 循环的想法是必不可少的。我们已经调整了您的解决方案,以便产生一定时间的超时 - 不间断。最好 Simpy 会在 yield 语句中添加一个 uninterrupted 关键字。 (类似于:yield env.timeout(15) uninterrupted
)。
我们最终得到了这样的解决方案:
remaining_time = time_to_wait
while remaining_time > 0:
try:
start = env.now
yield env.timeout(remaining_time)
except simpy.Interupt:
pass
finally:
elapsed = env.now - start
remaining_time -= elapsed