2

親スレッドがまだ生きているかスタックしているかどうかを確認する方法を知りたいです。基本的に、子にコマンドを送信する親スレッドがあります。親スレッドが停止したり、デッドロック状態になったりした場合、子スレッドを存続させたくありません。以下は、これまでの私の実装の基本的なフレームワークです。

from Queue import Queue
from threading import Thread

    class myClass:

        def __init__(self):

            self.currentCommand = Queue()           
            t = Thread(target=self._run)
            t.start()            

        def close(self):
            self._sendCommand("close")

        def _run(self):
            while True:
                if self.currentCommand.empty():
                    pass
                    #do some task
                else:
                    command = self.currentCommand.get()
                    if command == "close":
                        #clean up
                        self.currentCommand.task_done()
                        break
                    else:
                        #do command task
                        self.currentCommand.task_done()

        def _sendCommand(self, command):
            self.currentCommand.put(command)
            self.currentCommand.join()

私が持っているアイデアの 1 つは、コンピュータの時間を親から子に定期的に送信することです。時間が設定値よりも大きい場合、子供は死亡します。もっと簡単で効果的な方法はありますか?また、Python のドキュメントには、スレッド クラス内に isAlive メソッドがありますが、その使用方法がわかりません。

4

3 に答える 3

2

オブジェクトを子スレッドに渡すだけでEvent、親が終了を示したかどうかを確認できます。次に、親スレッドのクリティカル セクションを、finally何があってもビットを設定するでラップするだけです。

import time
from threading import Thread, Event


def child(quit):
    for _ in xrange(10):
        if quit.isSet():
            print "Parent is dead. Leaving child."
            return

        print "Child alive"
        time.sleep(.5)

def parent():
    quitEvent = Event()
    t = Thread(target=child, args=(quitEvent,))
    t.start()

    try:
        time.sleep(2)
        raise Exception("Parent thread raises exception")
    finally:
        quitEvent.set()

    t.join()


if __name__ == "__main__":
    t = Thread(target=parent, args=())
    t.start()
    t.join()

それ自体の作業中に親スレッドがデッドロックするという問題は、おそらくあなたが提案したような「ハートビート」アプローチが必要になるでしょうが、定期的にそれが生きていることを示しています。子に渡すキューを使用してこれを行うことも、引き続き Event オブジェクトを使用することもできます。親は定期的にイベントを設定し、子は特定の間隔で設定されることを期待し、その後すぐにクリアします。

Event親がデッドロックしてチェックインしていない可能性がある場合に、 をハートビートとして使用する例を次に示します。

def child(heartbeat):
    for _ in xrange(10):
        if not heartbeat.isSet():
            print "Parent is dead. Leaving child."
            return

        heartbeat.clear()

        print "Child alive"
        time.sleep(1)

def parent():
    heartbeat = Event()
    heartbeat.set()

    t = Thread(target=child, args=(heartbeat,))
    t.start()

    i = 0
    while i < 20:
        print "Parent alive"
        i += 1
        heartbeat.set()
        time.sleep(.1)

    print "Parent done looping...pretending to be deadlocked"
    time.sleep(5)

    t.join()

親は独自の作業を行っているため、ハートビート ビットを設定しています。子は定期的にこのビットをチェックしています。親が設定されていないことが判明した場合は、親が死んでいると見なして終了します。適切なハートビート間隔を確立する必要があります。親は、子供がチェックしているよりも頻繁にチェックインする必要があります。そうしないと、子供がすぐにチェックインして、親がいなくなったと思うかもしれません。

于 2012-11-07T19:06:12.253 に答える
1

isAlife親スレッドオブジェクトを子と何らかの方法で共有する場合に使用できます。

parent_thread = None

def child():
   while True:
       time.sleep(1)
       if not parent_thread.isAlive():
           break
       print('child alife')


def parent():
    t = threading.Thread(target=child)
    t.start()
    for i in range(10):
        print('parent alife')
        time.sleep(1)

parent_thread = threading.Thread(target=parent)
parent_thread.start()
于 2012-11-07T19:33:13.530 に答える
0

次の行を使用できます。

threading.main_thread().is_alive()
于 2021-12-22T13:55:36.877 に答える