2013-01-14 80 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

相關問題