2013-08-21 18 views
11

私は並行して実行する一連のタスクを持っていますが、最後に例外がスローされたスレッドがあるかどうかを知る必要があります。 は私が直接例外を処理する必要はありません、私はいずれかのスレッドが例外で失敗したかどうかを知る必要があるので、私はきれいにここPythonスレッドが例外をスローしたかどうかを確認します

は簡単な例であるスクリプトを終了することができます

#!/usr/bin/python 

from time import sleep 
from threading import Thread 

def func(a): 
    for i in range(0,5): 
     print a 
     sleep(1) 

def func_ex(): 
    sleep(2) 
    raise Exception("Blah") 


x = [Thread(target=func, args=("T1",)), Thread(target=func, args=("T2",)), Thread(target=func_ex, args=())] 

print "Starting" 
for t in x: 
    t.start() 

print "Joining" 
for t in x: 
    t.join() 


print "End" 

「終了」の前に、スレッドを繰り返し処理し、失敗したかどうかを確認してから、スクリプトを続行できるかどうか、またはこの時点で終了する必要があるかどうかを判断します。

私は例外を傍受したり、他のスレッドを停止する必要はありません。失敗した場合は、最後に知っておく必要があります。

答えて

7

join()スレッドが呼び出しを返すまでに、スレッドのスタックが解放され、例外に関するすべての情報が失われました。したがって、残念ながら例外を登録するための独自のメカニズムを提供する必要があります。いくつかの技術については、hereを参照してください。

1

例外を処理する必要がない場合のための簡単な手法は、グローバルリストを使用してそれに関連情報を追加することです。

#!/usr/bin/python 

from time import sleep 
from threading import Thread, current_thread #needed to get thread name or whatever identifying info you need 

threadErrors = [] #global list 

def func(a): 
    for i in range(0,5): 
     print a 
     sleep(1) 

def func_ex(): 
    global threadErrors #if you intend to change a global variable from within a different scope it has to be declared 
    try: 
     sleep(2) 
     raise Exception("Blah") 
    except Exception, e: 
     threadErrors.append([repr(e), current_thread.name]) #append a list of info 
     raise #re-raise the exception or use sys.exit(1) to let the thread die and free resources 

x = [Thread(target=func, args=("T1",)), Thread(target=func, args=("T2",)), Thread(target=func_ex, args=())] 

print "Starting" 
for t in x: 
    t.start() 

print "Joining" 
for t in x: 
    t.join() 

if len(threadErrors) > 0: #check if there are any errors 
    for e in threadErrors: 
     print(threadErrors[e][0]+' occurred in thread: '+threadErrors[e][1]) 
     #do whatever with each error info 
else: 
    #there are no errors so do normal clean-up stuff 

#do clean-up that should happen in either case here 

print "End" 

注:グローバル変数は、一般的に貧弱な技術とみなされ、しかし彼らは、スレッド間で通信するためのシンプルなメカニズムであるあなたのコードのようなものになるでしょう。あるスレッドがこのルートによって情報を送信している場合、もう1つのスレッドはそれを探していなければならないことを覚えておく必要があります。

関連する問題