2016-01-02 3 views
5

スレッド(大規模なデータベーステーブルを反復処理中)でプロセスを実行したいと思います。スレッドが実行されている間、私はプログラムを待つだけです。そのスレッドが30秒以上かかる場合は、スレッドを強制終了して別のことをしたい。スレッドを殺すことで、私はそれが活動を中止し、資源を優雅に解放したいということです。ある程度の時間の後にスレッドを殺す最もPythonの方法

私はこれを行うための最善の方法は、Thread()join(delay)is_alive()機能を介していた考え出し、およびEventjoin(delay)私のプログラムはスレッドが終了するまで30秒待つことができ、is_alive()関数を使って、スレッドが処理を終えたかどうかを判断できます。作業が終了していない場合は、イベントが設定され、スレッドはその時点で作業を停止することがわかります。

このアプローチは有効ですか、これは私の問題に関する声明を書く最も無邪気な方法ですか?ここで

は、いくつかのサンプルコードは次のようになります。この場合、イベントを使用して

import threading 
import time 

# The worker loops for about 1 minute adding numbers to a set 
# unless the event is set, at which point it breaks the loop and terminates 
def worker(e): 
    data = set() 
    for i in range(60): 
     data.add(i) 
     if not e.isSet(): 
      print "foo" 
      time.sleep(1) 
     else: 
      print "bar" 
      break 

e = threading.Event() 
t = threading.Thread(target=worker, args=(e,)) 
t.start() 

# wait 30 seconds for the thread to finish its work 
t.join(30) 
if t.is_alive(): 
    print "thread is not done, setting event to kill thread." 
    e.set() 
else: 
    print "thread has already finished." 

答えて

2

は、シグナリングメカニズムとしてだけで正常に動作している、と は実際threading module docsで推奨されます。

あなたのスレッドは、正常に停止彼らは非鬼神の作りや、Eventとして 、適切なシグナリングメカニズムを使用したい場合。

スレッド終了を検証するとき、タイムアウトはほとんど常に エラーのための領域を導入します。したがって、最初に のイベントをトリガーすることを決定するためのタイムアウトを伴う.join()を使用している間は、 .join()をタイムアウトなしに使用して最終的な検証を行う必要があります。

# wait 30 seconds for the thread to finish its work 
t.join(30) 
if t.is_alive(): 
    print "thread is not done, setting event to kill thread." 
    e.set() 
    # The thread can still be running at this point. For example, if the 
    # thread's call to isSet() returns right before this call to set(), then 
    # the thread will still perform the full 1 second sleep and the rest of 
    # the loop before finally stopping. 
else: 
    print "thread has already finished." 

# Thread can still be alive at this point. Do another join without a timeout 
# to verify thread shutdown. 
t.join() 

これは、このような何かを簡素化することができます。

# Wait for at most 30 seconds for the thread to complete. 
t.join(30) 

# Always signal the event. Whether the thread has already finished or not, 
# the result will be the same. 
e.set() 

# Now join without a timeout knowing that the thread is either already 
# finished or will finish "soon." 
t.join() 
関連する問題