2012-05-03 16 views
7

私は数多くのスレッドを生成するPythonプログラムを持っています。これらのスレッドは、2秒から30秒の範囲で持続します。メインスレッドでは、各スレッドが完了してメッセージを出力するたびに追跡します。私がちょうどすべてのスレッドを.join()して、最初のスレッドが30秒間続き、もう少し早く完了すると、すぐにメッセージを印刷することはできません。すべてのメッセージは30秒後に印刷されます。Pythonスレッドでは、スレッドの完了をどのように追跡できますか?

基本的には、までスレッドが完了するまでブロックします。スレッドが完了するとすぐに、そのスレッドに関するメッセージを表示し、他のスレッドがまだ生存している場合はブロックするように戻ります。すべてのスレッドが完了したら、プログラムを終了します。

私が考えることができる1つの方法は、すべてのスレッドに渡され、queue.get()でブロックされるキューを持つことです。メッセージがキューから受信されるたびに、それを表示し、threading.active_count()を使用して他のスレッドが存在するかどうかを確認し、そうであればqueue.get()でブロックする。これは動作しますが、ここではすべてのスレッドが終了する前にキューにメッセージを送信するという規律に従う必要があります。

これがこの動作を達成するための従来の方法であるのか、他の/より良い方法があるのでしょうか?

答えて

3

ここでは、代わりにあなたのターゲット機能からそれらを印刷する、あなたのメインスレッドからのメッセージを指定することができます@ detlyの答えのバリエーションがあります:

はここで、迅速かつ簡単なデモです。これはラッパー関数を作成してターゲットを呼び出し、終了する前にメッセージを出力します。各スレッドの完了後にこれを修正して、あらゆる種類の標準クリーンアップを実行できます。

#!/usr/bin/python 

import threading 
import time 

def target1(): 
    time.sleep(0.1) 
    print "target1 running" 
    time.sleep(4) 

def target2(): 
    time.sleep(0.1) 
    print "target2 running" 
    time.sleep(2) 

def launch_thread_with_message(target, message, args=[], kwargs={}): 
    def target_with_msg(*args, **kwargs): 
     target(*args, **kwargs) 
     print message 
    thread = threading.Thread(target=target_with_msg, args=args, kwargs=kwargs) 
    thread.start() 
    return thread 

if __name__ == '__main__': 
    thread1 = launch_thread_with_message(target1, "finished target1") 
    thread2 = launch_thread_with_message(target2, "finished target2") 

    print "main: launched all threads" 

    thread1.join() 
    thread2.join() 

    print "main: finished all threads" 
0

私は私が使用して問題を参照してくださいわからない: threading.activeCount()

をまだアクティブなスレッドの数を追跡するために?

起動する前に起動するスレッドの数がわからなくても、それを追跡するのはかなり簡単です。私は通常、リストの理解を介してスレッドのコレクションを生成し、リストのサイズにactiveCountを使用して単純な比較は、あなたがどれだけ完了したかを伝えることができます。

こちらをご覧ください:http://docs.python.org/library/threading.html

代わりに、あなたはあなたのスレッドはあなただけチェックするスレッドオブジェクト内.isAliveメソッドを使用することができますオブジェクトを持っていたら。

私はちょうど私が持っているマルチスレッドプログラムにこれを投げることによってチェックし、それが正常に見える:スレッドがオンとオフと

for thread in threadlist: 
     print(thread.isAlive()) 

は私にFALSE TRUE /のリストを提供します。だから、スレッドが終了したかどうかを確認するために、それを実行してFalseをチェックできるはずです。

1

スレッドに結果をthreading.Queueにプッシュさせることができます。別のスレッドがこのキューで待機し、新しい項目が表示されるとすぐにメッセージを印刷します。

4

Thread.is_alive()コールを使用してスレッドをチェックする必要があります。私は何を示唆している

2

は1秒睡眠があり、この

while len(threadSet) > 0: 
    time.sleep(1) 
    for thread in theadSet: 
     if not thread.isAlive() 
      print "Thread "+thread.getName()+" terminated" 
      threadSet.remove(thread) 

のようなループであるので、印刷されているスレッドの終了とメッセージの間にわずかな遅延が発生します。この遅れで暮らすことができれば、これはあなたの質問で提案したものより簡単な解決策だと私は考えています。

3

スレッド自身が完了メッセージを表示するだけでなく、終了時に他の補完コールバックを呼び出すのはなぜですか?

これらのスレッドはメインプログラムからちょうどjoinです。完了メッセージがたくさん表示され、必要に応じてプログラムがすべて終了したら終了します。

#!/usr/bin/python 

import threading 
import time 

def really_simple_callback(message): 
    """ 
    This is a really simple callback. `sys.stdout` already has a lock built-in, 
    so this is fine to do. 
    """  
    print message 

def threaded_target(sleeptime, callback): 
    """ 
    Target for the threads: sleep and call back with completion message. 
    """ 
    time.sleep(sleeptime) 
    callback("%s completed!" % threading.current_thread()) 

if __name__ == '__main__': 
    # Keep track of the threads we create 
    threads = [] 

    # callback_when_done is effectively a function 
    callback_when_done = really_simple_callback 

    for idx in xrange(0, 10): 
     threads.append(
      threading.Thread(
       target=threaded_target, 
       name="Thread #%d" % idx, 
       args=(10 - idx, callback_when_done) 
      ) 
     ) 

    [t.start() for t in threads] 
    [t.join() for t in threads] 

    # Note that thread #0 runs for the longest, but we'll see its message first! 
0

私は自分のアプリケーションで使用したスレッドの性質上、少し異なるテクニックを使用します。

while threads: 
     finished = set(threads) - set(threading.enumerate()) 
     while finished: 
      ttt = finished.pop() 
      threads.remove(ttt) 
     time.sleep(0.5) 

は、なぜ私はそれをこのように行うのですか?説明するために、これは私が私のスレッドクラスのバリアクラスを骨格に書いたテストストラッププログラムの断片でありますか私の生産コードでは時間制限があるので、最初の行は実際にはスレッドとtime.time()< cutoff_timeの間に読み込まれます。カットオフに達すると、スレッドをシャットダウンするように指示するコードがあります。

関連する問題