6

最初の方法:

import threading
import time

def keepalive():
    while True:
        print 'Alive.'
        time.sleep(200)
threading.Thread(target=keepalive).start()

2番目の方法:

import threading

def keepalive():
    print 'Alive.'
    threading.Timer(200, keepalive).start()

threading.Timer(200, keepalive).start()

どの方法がより多くのRAMを消費しますか?そして2番目の方法では、スレッドはアクティブ化された後に終了しますか?または、メモリに残り、新しいスレッドを開始しますか?(複数のスレッド)

4

2 に答える 2

8

Timer開始されたタイマーごとに新しいスレッド オブジェクトを作成するため、これらのオブジェクトを作成およびガベージ コレクションするときにより多くのリソースが必要になります。

各スレッドは、生成された直後に終了するため、別のactive_countスレッドは一定のままですが、常に新しいスレッドが作成および破棄され、オーバーヘッドが発生します。最初の方法が間違いなく優れていると思います。

間隔が非常に小さい場合にのみ、実際には大きな違いは見られませんが。

于 2012-11-07T01:19:05.183 に答える
5

これを自分でテストする方法の例を次に示します。

そして2番目の方法では、スレッドはアクティブ化された後に終了しますか?または、メモリに残り、新しいスレッドを開始しますか?(複数のスレッド)

import threading

def keepalive():
    print 'Alive.'
    threading.Timer(200, keepalive).start()
    print threading.active_count()

threading.Timer(200, keepalive).start()

また、200を.2に変更したので、それほど時間はかかりません。

スレッド数は永久に3でした。

それから私はこれをしました:

top -pid 24767

#TH列は変更されませんでした。

だから、あなたの答えがあります:Pythonがすべてのタイマーに対して単一のタイマースレッドを維持するのか、タイマーが実行されるとすぐにスレッドを終了してクリーンアップするのかを知るのに十分な情報がありませんが、スレッドがそうではないことは確かです立ち往生して積み重ならないでください。(前者のどちらが発生しているかを知りたい場合は、たとえば、スレッドIDを出力できます。)

調べる別の方法は、ソースを調べることです。ドキュメントに記載されているように、「タイマーはスレッドのサブクラスであり、カスタムスレッドを作成する例としても機能します」。それがのサブクラスであるという事実は、それぞれがであるということをThreadすでに示しています。そして、それが「例として機能する」という事実は、それが読みやすいはずであることを意味します。ドキュメントからソースへのリンクをクリックすると、それがいかに簡単であるかがわかります。ほとんどの作業はによって行われますが、それは同じソースファイルにあり、ほぼ同じくらい簡単です。事実上、条件変数を作成し、それを待機して(タイムアウトになるまでブロックするか、を呼び出して条件を通知する)、終了します。TimerThreadEventcancel

各サブ質問に答えるのではなく、1つのサブ質問に答えて、それをどのように行ったかを説明する理由は、同じ手順を実行する方が便利だと思うからです。

さらに考えてみると、これはおそらく、そもそも最適化によって決定される問題ではありません。

200秒間何もする必要のない単純な同期プログラムがある場合は、にブロッキング呼び出しを行いsleepます。または、さらに簡単に、ジョブを実行して終了し、外部ツールを選択して、スクリプトを200秒ごとに実行するようにスケジュールします。

一方、プログラムが本質的に非同期である場合(特に、スレッド、シグナルハンドラー、イベントループが既にある場合)、作業を開始する方法はありませんsleepTimer非効率的すぎる場合は、PyPIまたはActiveStateに移動して、単一のインスタンスとスレッドで繰り返し可能なタイマー(または複数のタイマー)をスケジュールできる、より優れたタイマーを見つけてください。(または、シグナルを使用している場合は、signal.alarmまたはsetitimerを使用し、イベントループを使用している場合は、タイマーをメインループに組み込みます。)

両方が深刻な競争相手になるようなsleepユースケースは考えられません。Timer

于 2012-11-07T01:04:41.223 に答える