简单的中断条件事件

时间:2017-01-22 09:27:58

标签: simulation simpy

这里简单的新手。我刚开始用简单的方式进行扬声器 - 主持人模拟。这是我的代码

import simpy

def speaker(env):
    try:
        print("Speaker start to talk at: {}".format(env.now))
        speak_time = 40
        print ("Speaker want to speak for {}".format(speak_time))
        yield env.timeout(speak_time)
        print ("Speaker finish the talk at: {}".format(env.now))
   except simpy.Interrupt as interrupt:
        print (interrupt.cause)

def moderator(env):
    for i in range(3):
        print("Moderator let the speaker number {} to begin the speak".format(i))
        speaker_proc = env.process(speaker(env))

        print("Time now: {}".format(env.now))
        time_limit = env.timeout(30)
        results = yield speaker_proc | time_limit
        print("Moderator check whether speaker passed the time limit or no")
        print("Time limit passed: {}".format (speaker_proc not in results))


        if speaker_proc not in results:
            print("Time now: {}".format(env.now))
            speaker_proc.interrupt()
            print ("Moderator stop the talk at: {}".format(env.now))
        print()
        print()

env = simpy.Environment()
env.process(moderator(env))
env.run()    

当我使用speak_time>运行它时30或speak_time< 30,没有问题,但是如果我改变功能扬声器中的speak_time变为30,它将会出现如下错误:

RuntimeError: <Process(speaker) object at 0x9e17930> has terminated and cannot be interrupted.

发生了什么事?

1 个答案:

答案 0 :(得分:0)

你在这里遇到一个奇怪的角落案件。虽然你观察到的行为是完全的 对于SimBy新手来说,这并不容易理解。

我在print()进程中添加了两个moderator()来显示正在发生的事情:

import simpy


def speaker(env):
    try:
        print("Speaker start to talk at: {}".format(env.now))
        speak_time = 30
        print("Speaker want to speak for {}".format(speak_time))
        yield env.timeout(speak_time)
        print("Speaker finish the talk at: {}".format(env.now))
    except simpy.Interrupt as interrupt:
        print(interrupt.cause)


def moderator(env):
    for i in range(3):
        print("Moderator let the speaker number {} to begin the speak".format(i))
        speaker_proc = env.process(speaker(env))

        print("Time now: {}".format(env.now))
        time_limit = env.timeout(30)
        print('Timeout created')
        results = yield speaker_proc | time_limit
        print("Moderator check whether speaker passed the time limit or no")
        print("Time limit passed: {}".format(speaker_proc not in results))

        if speaker_proc not in results:
            print("Time now: {}".format(env.now))
            print(speaker_proc.is_alive)
            speaker_proc.interrupt()
            print("Moderator stop the talk at: {}".format(env.now))
        print()
        print()

env = simpy.Environment()
env.process(moderator(env))
env.run()

输出:

Moderator let the speaker number 0 to begin the speak
Time now: 0
Timeout created
Speaker start to talk at: 0
Speaker want to speak for 30
Speaker finish the talk at: 30
Moderator check whether speaker passed the time limit or no
Time limit passed: True
Time now: 30
False
Traceback (most recent call last):

那发生了什么?

  1. 主持人在第一次yield之前一直有效。那段时间,它 创建演讲者流程和超时。

  2. 立即触发超时并将其添加到事件队列中。

  3. 主持人产生条件事件。

  4. 扬声器运行并创建超时。它也会立即触发 和预定(与主持人的超时同时,但它是 在事件队列中插入后。)

  5. 处理主持人的超时时会触发Condition事件。

  6. 当主持人恢复时,条件事件仅保留结果 主持人的超时,但扬声器进程也终止了。您可以 通过speaker_proc.is_alive属性检查。

  7. This guide包含一些有关此内容的更深入信息 主题。