3

私はPythonが初めてなので、これが明らかな場合は申し訳ありません。

マルチスレッドアプリケーションを構築しようとしていますが、スレッドを作成したいときに、1 つではなく 2 つ取得します。

MyThread.py

from threading import Thread
import time

class MyThreadClass(Thread):

    def __init__(self):
        Thread.__init__(self)

    def run(self):
        print "starting " + self.getName() + "\n"
        from main import var1
        while True:
            print self.getName() + " is running\n"
            print "value: " + var1 + "\n"
            time.sleep(1)

main.py

from MyThread import MyThreadClass
var1 = "Test"
MyThreadClass().start()

私が得る出力

 Thread-1 is running
 Thread-2 is running
 Thread-1 is running
 Thread-2 is running
 Thread-1 is running
 Thread-2 is running
 .....

なぜそれが起こっているのですか?MyThreadClass().start()に置き換えるとMyThreadClass().run()2つのスレッドが得られますが、そのうちの1つだけが実行され続けることに気付きました

 Thread-1 is running
 Thread-2 is running
 Thread-2 is running
 Thread-2 is running
 Thread-2 is running
 .....

コードの何が問題なのか分かりますか?

4

2 に答える 2

9

にインポートmain.pyするMyThread.pyと、行

MyThreadClass().start()

(モジュールがロードされるため) もう一度実行されるため、2 番目のスレッドが開始されます。


main.pyその行を次のように置き換えることで、ガード句を作成できます

if __name__ == "__main__":
    MyThreadClass().run()

または、循環依存を回避するためにパラメーターとしてvar1渡すだけです。MyThreadClass

MyThread.py :

from threading import Thread
import time

class MyThreadClass(Thread):

    def __init__(self, var1):
        Thread.__init__(self)
        self.var1 = var1

    def run(self):
        print "starting " + self.getName() + "\n"
        while True:
            print self.getName() + " is running\n"
            print "value: " + self.var1 + "\n"
            time.sleep(1)

main.py

from MyThread import MyThreadClass

if __name__ == "__main__":
    MyThreadClass("Test").run()
于 2012-08-28T12:10:25.810 に答える
4

スレッドを 2 回開始します。1 回は実行時main.py(モジュールであるため)、もう 1 回はのメソッド__main__にインポートするときに実行されます。MyThreadClassrun()

importステートメントは、要求したものだけでなく、モジュール内のすべてのコードを実行します。フォームは、from特定のアイテムを現在の名前空間に持ち込むのに便利です。

2 スレッドで停止する理由は、2 番目のスレッドで再度インポートしてもmain、モジュールのコードが既に読み込まれているため、Python がモジュールのコードを再実行しないためです。それがなかったら、2 つ以上のスレッドがあったでしょう ;-)

他の回答if __name__ == '__main__':で言及されている構造を使用すると、この状況だけでなく、すべてのタイプのモジュールで非常に役立ちます。これにより、それらを実行し (多くのモジュールがテスト コードにこれを使用します)、副作用を回避しながらインポートすることができるためです。

于 2012-08-28T12:13:31.827 に答える