2013-08-21 30 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" 

注:全局变量通常被视为技术差,他们线程间通信的简单机制。你只需要记住,如果一个线程通过这个路由发送信息,另一个线程必须寻找它。