2013-01-14 41 views
1

可能重复:
Catch a thread’s exception in the caller thread in Pythonthread.start_new_thread:转让例外主线程

我有一个给定的代码,有一个

thread.start_new_thread() 

正如我刚才在python doc中读取:“当函数以未处理的异常终止时,会打印一个堆栈跟踪,然后是thre广告退出(但其他线程继续运行)。“ 但是,当(新)函数终止异常时,我也想终止主线程 - 所以异常应该传递给主线程。我怎样才能做到这一点?

编辑: 这里是我的代码部分:

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

对我来说似乎是另一个问题,而不是重复。如果“给定代码”是指“不能修改的第三方代码”,则问题完全不同。 – Ellioh

+0

对不起,“一个给定的代码”意味着我没有写它,所以我不是很熟悉它 - 但我可以修改它。 – Munchkin

+0

那么我的第一个答案是不是你的问题,和猴子修补线程是一个坏主意。 :-) – Ellioh

回答

0

UPD:这不是你的问题的最佳解决方案是什么,我认为这是不同的:我希望你在试图处理在线程代码中您不能修改的例外。但是,我决定不删除答案。

很难从另一个线程捕获异常。通常它应该手动转移。

你可以包装一个线程函数吗?如果您缠绕工作线程撞向试试......除了,那么您可以在except块进行退出主线程需要采取的行动(sys.exit似乎是无用的,虽然这是一个让我吃惊,但有thread.interrupt_main()os.abort(),虽然你可能需要更优雅的东西,比如设置一个主线程定期检查的标志)。

但是,如果您不能修改函数(无法修改调用start_new_thread的第三方代码),您可以尝试对线程模块(或第三方模块本身)进行修补。的start_new_thread()修补版本应该换你担心的功能:在t()原因thread.interrupt_main()/os.abort()

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) 

这里异常。应用程序中的其他线程函数不受影响。

+0

感谢您的回答! new_thread中的sys.exit()不会终止主线程:“sys.exit()[...]只会在从主线程[...]调用时退出进程”(http:// docs.python.org/2/library/sys.html)所以它不适用于我。我编辑了我的第一篇文章并添加了一部分代码。 – Munchkin

+0

哇......真的,它本身引发了一个异常...... – Ellioh

+0

修复它使用thread.interrupt_main() – Ellioh

相关问题