13

次のクラスを想像してください。

Class Object(threading.Thread):
    # some initialisation blabla
    def run(self):
        while True:
            # do something
            sleep(1)

class Checker():
    def check_if_thread_is_alive(self):
        o = Object()
        o.start()

        while True:
            if not o.is_alive():
                o.start()

スレッドが死んでいる場合に備えて、スレッドを再起動したい。これはうまくいきません。スレッドは一度しか開始できないためです。最初の質問。どうしてこれなの?

私が知る限り、各インスタンスを再作成しObject、呼び出しstart()てスレッドを再度開始する必要があります。複雑なObjects の場合、これはあまり実用的ではありません。古い の現在の値を読み取り、Object新しいオブジェクトを作成し、新しいオブジェクトのパラメータを古い値で設定する必要があります。2 番目の質問: これをよりスマートで簡単な方法で行うことはできますか?

4

3 に答える 3

17

threading.Thread がそのように実装されている理由は、スレッド オブジェクトとオペレーティング システムのスレッドとの間の対応を維持するためです。主要な OS ではスレッドを再開できませんが、別のスレッド ID で別のスレッドを作成することはできます。

再作成が問題になる場合は、threading.Thread からクラスを継承する必要はありません。次のように、ターゲット パラメーターを Thread のコンストラクターに渡すだけです。

class MyObj(object):
    def __init__(self):
        self.thread = threading.Thread(target=self.run)
    def run(self):
        ...

次に、スレッド メンバーにアクセスしてスレッドの実行を制御し、必要に応じて再作成することができます。MyObj の再作成は必要ありません。

于 2013-01-12T12:43:57.320 に答える
1

ここを参照してください: http://docs.python.org/2/library/threading.html#threading.Thread.start

スレッド オブジェクトごとに最大 1 回呼び出す必要があります。オブジェクトの run() メソッドが別の制御スレッドで呼び出されるように調整します。

このメソッドは、同じスレッド オブジェクトで複数回呼び出されると、RuntimeError を発生させます。

スレッドは、複数回実行することを意図していません。スレッドプールを使用したい場合があります

于 2013-01-12T12:44:04.063 に答える
0

Threadそれは、クラスの実装方法に関係していると思います。これは実際の OS スレッドをラップするため、スレッドを再起動すると実際にその ID が変更され、混乱を招く可能性があります。

スレッドを処理するより良い方法は、実際にはターゲット関数/呼び出し可能オブジェクトを使用することです。

class Worker(object):
    """ Implements the logic to be run in separate threads """
    def __call__(self):
        #  do useful stuff and change the state

class Supervisor():
    def run(self, worker):
        thr = None
        while True:
            if not thr or not thr.is_alive():
                thr = Thread(target=worker)
                thr.daemon = True
                thr.start()
            thr.join(1)  # give it some time
于 2013-01-12T12:48:57.840 に答える