15

次のコードで次の動作に気づきました(threading.Timerクラスを使用)。

import threading

def ontimer():
    print threading.current_thread()

def main():
    timer = threading.Timer(2, ontimer)
    timer.start()
    print threading.current_thread()
    timer.cancel()
    if timer.isAlive():
        print "Timer is still alive"
    if timer.finished:
        print "Timer is finished"


 if __name__ == "__main__":
main()

コードの出力は次のとおりです。

<_MainThread(MainThread, started 5836)>
Timer is still alive
Timer is finished

出力からわかるように、タイマーオブジェクトはまだ生きていて、同時に終了しています。

実際、私は同様の関数を何百回も呼び出したいのですが、それらの「生きている」タイマーがパフォーマンスに影響を与えるのではないかと思います。

タイマーオブジェクトを適切に停止またはキャンセルしたいのですが。私はそれを正しくやっていますか?

ありがとうございました

4

2 に答える 2

13

thread.join()を使用して、タイマーのスレッドが実際に終了してクリーンアップされるまで待機する必要があります。

import threading

def ontimer():
    print threading.current_thread()

def main():
    timer = threading.Timer(2, ontimer)
    timer.start()
    print threading.current_thread()
    timer.cancel()
    timer.join()         # here you block the main thread until the timer is completely stopped
    if timer.isAlive():
        print "Timer is still alive"
    else:
        print "Timer is no more alive"
    if timer.finished:
        print "Timer is finished"


 if __name__ == "__main__":
main()

これは表示されます:

<_MainThread(MainThread, started 5836)>
Timer is no more alive
Timer is finished
于 2012-06-18T13:31:11.550 に答える
12

ATimerはaのサブクラスでありThread、その実装は非常に簡単です。イベントにサブスクライブすることにより、指定された時間を待機しますfinished

したがって、によってイベントを設定Timer.cancelすると、関数が呼び出されないことが保証されます。ただし、タイマースレッドが直接続行(および終了)することは保証されていません。

つまり、の実行後もタイマーのスレッドは存続できますcancelが、関数は実行されません。したがって、チェックfinishedは安全ですが、Thread.is_alive(新しいAPI、これを使用してください!)のテストは、この場合の競合状態です。

ヒント:これを確認するには、time.sleepを呼び出した後にを配置しcancelます。次に、次のように出力します。

<_MainThread(MainThread, started 10872)>
Timer is finished
于 2012-06-18T13:27:22.917 に答える