web-dev-qa-db-ja.com

PythonスレッドThread-1の例外(ほとんどの場合、インタープリターのシャットダウン中に発生します)?

私の友人と私はpythonとPyGame。で学ぶために楽しみのために大きなプロジェクトに取り組んでいます。基本的にそれは小さな村のAIシミュレーションです。 numpy(具体的にはクロスフェードチュートリアル)を使用して表面全体の色を変更するきちんとした方法を見つけました- http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro.html

私はそれをコードに実装して動作しますが、1 fps未満のように非常に遅いです。だから私はスレッドを調べて(最終的に追加したかったので)、キューでこのページを見つけました- python(実行方法))でキューモジュールについて学ぶ

基本的なシステムの作成には約15分かかりますが、実行するとすぐにウィンドウが閉じて、

Exception in thread Thread-1 (most likely raised during interpreter shutdown):

編集:これは文字通りそれだけで、トレースバックエラーはありません

何が間違っているのかわかりませんが、単純なものが欠けていると思います。以下のコードの必要な部分を追加しました。

q_in = Queue.Queue(maxsize=0)

q_out = Queue.Queue(maxsize=0)

def run():    #Here is where the main stuff happens
    #There is more here I am just showing the essential parts
    while True:
        a = abs(abs(world.degree-180)-180)/400.

        #Process world
        world.process(time_passed_seconds)

        blank_surface = pygame.Surface(SCREEN_SIZE)
        world.render(blank_surface)    #The world class renders everything onto a blank surface
        q_in.put((blank_surface, a))
        screen.blit(q_out.get(), (0,0))

def DayNight():
    while True:
        blank_surface, a = q_in.get()
        imgarray = surfarray.array3d(blank_surface)  # Here is where the new numpy       stuff starts (AKA Day/Night cycle)
        src = N.array(imgarray)
        dest = N.zeros(imgarray.shape)
        dest[:] = 20, 30, 120
        diff = (dest - src) * a
        xfade = src + diff.astype(N.int)

        surfarray.blit_array(blank_surface, xfade)
        q_out.put(blank_surface)
        q_in.task_done()

def main():
    MainT = threading.Thread(target=run)
    MainT.daemon = True
    MainT.start()

    DN = threading.Thread(target=DayNight)
    DN.daemon = True
    DN.start()

    q_in.join()
    q_out.join()

誰か助けていただければ幸いです。ありがとうございました。

23
Nick Jarvis

デーモンスレッドを使用する場合、これは非常に一般的です。スレッドに_.daemon = True_を設定しているのはなぜですか?それについて考えてください。デーモンスレッドの正当な使用法はありますが、most混乱しているため、プログラマーは「スレッドをきれいにシャットダウンする方法がわからず、プログラムがフリーズする」などそうしないと終了するので、わかっています!デーモンスレッドだと言います。その後、インタープリターは終了時にそれらが終了するのを待ちません。問題は解決しました。」

しかし、それは解決されていません-通常、他の問題を引き起こすだけです。特に、インタプリタが-終了時に-自身を破壊している間、デーモンスレッドは実行を続けます。モジュールは破壊され、stdinとstdoutおよびstderrは破壊されます。など。デーモンスレッドでは、アクセスしようとしているものが消滅するため、あらゆる種類の問題が発生する可能性があります。

表示されている特定のメッセージは、あるスレッドで例外が発生したときに生成されますが、インタープリターが破壊されたため、sysモジュールにも使用可能なものが含まれなくなりました。スレッドの実装は_sys.stderr_への参照を内部的に保持しているため、something then(具体的には、表示されている正確なメッセージ)を伝えることができますが、インタープリターの多くが破壊されています何がうまくいかなかったかについて他に何かを教えてください。

そのため、代わりにスレッドをきれいにシャットダウンする方法を見つけてください(そして_.daemon = True_を削除してください)。特定の方法を示唆するほどあなたの問題について十分に知らないが、あなたは何かを考えるでしょう;-)

ところで、Queue()コンストラクターの_maxsize=0_引数を削除することをお勧めします。デフォルトは「無制限」であり、「誰もが知っている」のですが、_maxsize=0_も「無制限」を意味することを知っている人はほとんどいません。他のデータ型が_maxsize=0_を「最大サイズは実際には0」であると見なしているため、それはさらに悪化しています(その最良の例は_collections.deque_です)。しかし、「引数がないことは無制限であることを意味します」は、まだ普遍的に真実です。

49
Tim Peters