2013-05-11 155 views
2

我正在寫一個python程序,在主函數我開始一個線程連續運行。在啓動線程後,主函數進入一個while循環,並持續輸入用戶輸入。如果在子線程中有異常,我也想結束主函數。什麼是最好的方式來做到這一點?停止從主線程主線程

在此先感謝

回答

2

的Python讓你通過signal模塊訪問這個系統調用,這樣你就可以SIGINT註冊一個信號處理程序,做任何你喜歡的。順便提一下,缺省的SIGINT處理程序只會引發一個KeyboardInterrupt異常,所以如果您不想使用信號,則可以將整個程序放在try/except結構中,並獲得或多或少的相同效果。由於你想停止主線程在子線程中的任何崩潰,只需將整個while循環放在except Exception: try-except塊中。

這應該可以工作,但一些背景信息 - Python的信號模塊文檔明確指出,當多個線程正在運行時,只有主線程(即您的進程啓動時創建的線程)將接收信號(對於您而言,它不應該因爲你想要主線程中的信號)。所以信號處理程序將只在一個線程中執行,而不是全部執行。爲了讓所有線程停止響應信號,您需要主線程的信號處理程序將停止消息傳遞給其他子線程。這可以通過不同的方式完成,最簡單的方法是讓主線程翻轉所有子線程持有引用的布爾變量的值。這只是爲了捕獲一個場景,其中一個子線程崩潰並且信號發送到主線程以正常關閉,使用上述方法可以關閉子線程而不會突然終止它們。

7

有一個線程「控制」它的父母不是一個好習慣。主線程管理/監視/控制它啓動的線程更有意義。

所以我的建議是,你的主線程啓動2個線程:你已經擁有的那個線程,它在某一點完成/引發一個異常,以及一個閱讀用戶輸入。現在主線程等待(join s)爲前者完成,並退出一次完成。

from threading import Thread 
import time 

class ThreadA(Thread): 
    def run(self): 
     print 'T1: sleeping...' 
     time.sleep(4) 
     print 'T1: raising...' 
     raise RuntimeError('bye') 

class ThreadB(Thread): 
    def __init__(self): 
     Thread.__init__(self) 
     self.daemon = True 
    def run(self): 
     while True: 
      x = raw_input('T2: enter some input: ') 
      print 'GOT:', x 

t1 = ThreadA() 
t2 = ThreadB() 
t1.start() 
t2.start() 
t1.join() # wait for t1 to finish/raise 
print 'done' 

由於ThreadB是守護進程的,我們不必明確地停止它,也不必加入它。當主線程退出時,它也會退出。

國際海事組織,沒有必要訴諸像信號這樣的低層次東西。此解決方案甚至不需要使用try-except(儘管您可能會決定要在ThreadA中使用try-except,使其完全退出)。