SimPy中;如何合并未知数量的中断

时间:2015-05-14 12:03:13

标签: python simulation try-except simpy

我正在使用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

2 个答案:

答案 0 :(得分:1)

我取得了一些进展并想出了一个解决方案。

多个中断不需要嵌套的try except语句。单独的陈述似乎也有效。经过一些跟踪和错误后,我发现也可以使用单独的try except语句。

第一个中断启动计数器。每个中断都会增加计数器,而while循环可确保所有中断都得到处理。只要except不包含上述额外的yield语句,这就可以工作。

代码:

var currentUrl = document.referrer;
var okayUrl = "http://good-domain.com";
var okayUrl2 = "http://another-good-domain.com";

//check if page is loaded in iframe
if ( window.location !== window.parent.location ) {
    //check if parent is a whitelisted domain
    if (currentUrl == okayUrl || currentUrl == okayUrl2)
    {
     //if it is a good domain, then just log the parent url or something
     console.log(currentUrl);
     } else {
     //if it is a bad domain, then do something about it
     alert ("Woah buddy. Can't touch this!");
     window.location = "http://en.wikipedia.org/wiki/Rickrolling";
   }
}

答案 1 :(得分:1)

感谢您的帖子,对我们有很大帮助。使用while循环的想法至关重要。我们调整了您的解决方案,以实现一定时间的超时-不间断。 Simpy最好在yield语句中添加一个不间断的关键字。 (类似: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