2017-01-22 13 views
0

simpy новичок здесь. Я только начал создавать симулятор динамика-модератора с simpy. Вот мой кодПрерывание условное событие в 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. 

Что случилось?

ответ

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. Модератор дает условие conditon.

  4. Динамик работает и создает таймаут. Он также сразу же запускается и запланирован (одновременно с таймаутом модератора, но он вставлен после него в очередь событий).

  5. Событие Условие запускается при обработке таймаута модератора.

  6. Когда модератор возобновляется, событие условия содержит только результат ожидания модератора , но процессы динамиков также прекращаются. Вы можете связаться с нами через speaker_proc.is_alive.

This guide содержит некоторые более подробную информацию об этой теме.

+0

После прочтения некоторых примеров, в функции модератора процесса я меняю If-clause «если speaker_proc не в результатах:« станет «если не speaker_proc.triggered:», и он снова стал работать. Тем не менее, не знаю, почему это может снова работать. Я думаю, что снова прочитаю документацию – yusri

+0

Основная проблема заключается в том, что оба тайм-аута, модератор и динамик назначаются одновременно. Но так как они должны быть сериализованы, первая из модераторов get обрабатывается первой. Когда событие условия оценивается, время ожидания модератора уже обрабатывается, но процессы динамиков все еще находятся в очереди. Таким образом, событие состояния знает об этом. Когда модератор возобновляется, динамики обрабатываются. –