可能重复:
Catch a thread’s exception in the caller thread in Python
我有一个给定的代码,并且有一个
thread.start_new_thread()
正如我刚才读到的python doc:“当函数以未处理的异常终止时,会打印一个堆栈跟踪,然后线程退出(但其他线程继续运行)。” 但是当(新)函数以异常终止时我想终止主线程 - 所以异常应该转移到主线程。我怎么能这样做?
编辑: 这是我的代码的一部分:
def CaptureRegionAsync(region=SCREEN, name="Region", asyncDelay=None, subDir="de"):
if asyncDelay is None:
CaptureRegion(region, name, subDir)
else:
thread.start_new_thread(_CaptureRegionAsync, (region, name, asyncDelay, subDir))
def _CaptureRegionAsync(region, name, asyncDelay, subDir):
time.sleep(max(0, asyncDelay))
CaptureRegion(region, name, subDir)
def CaptureRegion(region=SCREEN, name="Region", subDir="de"):
...
if found:
return
else:
raise Exception(u"[warn] Screenshot has changed: %s" % filename)
CaptureRegionAsync(myregion,"name",2)
答案 0 :(得分:0)
UPD:这不是最佳解决方案,因为您的问题与我的想法不同:我希望您尝试处理无法修改的线程代码中的异常。但是,我决定不删除答案。
很难从另一个线程中捕获异常。通常应该手动转移。
你能包装一个线程函数吗?如果你将崩溃的工作线程包装成try ...除外,那么你可以执行退出except
块中的主线程所需的操作(sys.exit
似乎没用,虽然这对我来说很意外,但是有thread.interrupt_main()
和os.abort()
,但你可能需要一些更优雅的东西,比如设置主要线程定期检查的标志。)
但是,如果您无法包装该函数(无法修改调用start_new_thread
的第三方代码),您可以尝试猴子修补线程模块(或第三方模块本身)。修补版start_new_thread()
应该包含你担心的函数:
import thread
import sys
import time
def t():
print "Thread started"
raise Exception("t Kaboom")
def t1():
print "Thread started"
raise Exception("t1 Kaboom")
def decorate(s_n_t):
def decorated(f, a, kw={}):
if f != t:
return s_n_t(f, a, kw)
def thunk(*args, **kwargs):
try:
f(*args, **kwargs)
except:
print "Kaboom"
thread.interrupt_main() # or os.abort()
return s_n_t(thunk, a, kw)
return decorated
# Now let's do monkey patching:
thread.start_new_thread = decorate(thread.start_new_thread)
thread.start_new_thread(t1, ())
time.sleep(5)
thread.start_new_thread(t, ())
time.sleep(5)
此处t()
中的例外导致thread.interrupt_main()
/ os.abort()
。应用程序中的其他线程函数不受影响。