2017-01-22 4 views
0

simpy初心者はこちらです。私はちょうどsimpyでSpeaker-Moderatorシミュレーションを始めました。ここで私はspeak_time> 30またはspeak_time < 30でそれを実行すると、私のコード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になる:

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

何が起こったのですか?

答えて

0

ここでは奇妙なコーナーケースをヒットします。あなたが観察した行動は、完全に を意図していますが、SimBy初心者にとってはそれほど簡単ではありません。

私は何が起こっているのかを示すために、あなたのmoderator()プロセスに2 print()を追加しました:

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. 司会者のタイムアウトが処理されると、Conditionイベントがトリガーされます。

  6. モデレータが再開されると、条件イベントは モデレータのタイムアウトの結果を保持しますが、スピーカプロセスも終了します。これはspeaker_proc.is_aliveプロパティで確認できます。

This guideこの トピックに関するいくつかのより詳細な情報が含まれています。

+0

司会者の処理機能では、「speaker_procが結果にない場合」というIf節を「speaker_proc.triggeredではない」に変更し、再び動作するようになりました。それでも、なぜそれが再び働くのか分かりません。私は再びドキュメンテーションを読むと思う。 – yusri

+0

基本的な問題は、タイムアウトとモデレーターとスピーカーの両方が同時にスケジュールされていることです。しかし、それらを直列化しなければならないので、司会者のものが最初に処理されます。条件イベントが評価されると、モデレータタイムアウトは既に処理されていますが、スピーカープロセスはまだキューにあります。したがって、条件イベントはこれを知っています。モデレータが再開すると、スピーカは処理されます。 –

関連する問題