2

シミュレーションに python と simpy を使用しています。シミュレーションでは、1 つのインスタンス (中断) が別のインスタンス (中断) によって中断される可能性があります。割り込みごとにネストされた try except ステートメントを使用します。ネストされた try except ステートメントは、中断の最大回数がわかっている場合に機能します。

問題は、中断が何回発生するかわからないことです (1、2、3、... の可能性があります)。何度も中断されたオブジェクトを処理する方法がわかりません。

以下のコードは 3 回の中断に対して機能しますが、4 回目の中断が含まれると機能しなくなります (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')

使用したバージョン:

  • パイソン: 2.7.3
  • シンピー: 3.0.7
4

2 に答える 2

2

私はいくつかの進歩を遂げ、解決策を思いつきました。

複数の割り込みには、ネストされた 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)
于 2015-05-15T19:31:58.373 に答える