20

並行して実行する一連のタスクがありますが、それらの最後に、いずれかのスレッドが例外をスローしたかどうかを知る必要があります。例外を直接処理する必要はありません。スレッドの 1 つが例外で失敗したかどうかを知る必要があるだけなので、スクリプトをきれいに終了できます。

簡単な例を次に示します。

#!/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"

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

例外をインターセプトしたり、他のスレッドを停止したりする必要はありません。失敗したかどうかを最後に知る必要があるだけです。

4

3 に答える 3

12

スレッドのjoin()呼び出しが戻るまでに、スレッドのスタックは巻き戻されており、例外に関するすべての情報は失われています。したがって、残念ながら、例外を登録するための独自のメカニズムを提供する必要があります。ここでは、いくつかのテクニックについて説明します

于 2013-08-21T06:33:36.563 に答える
3

例外を処理する必要がない場合の簡単な方法は、グローバル リストを使用して関連情報を追加することです。コードは次のようになります。

#!/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"

注:グローバル変数は、一般的に貧弱な手法と見なされています、スレッド間で通信するための単純なメカニズムです。あるスレッドがこのルートで情報を送信している場合、他のスレッドがそれを探している必要があることを覚えておく必要があります。

于 2016-02-24T22:03:00.613 に答える