我正在寫一個python程序,在主函數我開始一個線程連續運行。在啓動線程後,主函數進入一個while循環,並持續輸入用戶輸入。如果在子線程中有異常,我也想結束主函數。什麼是最好的方式來做到這一點?停止從主線程主線程
在此先感謝
我正在寫一個python程序,在主函數我開始一個線程連續運行。在啓動線程後,主函數進入一個while循環,並持續輸入用戶輸入。如果在子線程中有異常,我也想結束主函數。什麼是最好的方式來做到這一點?停止從主線程主線程
在此先感謝
的Python讓你通過signal模塊訪問這個系統調用,這樣你就可以SIGINT
註冊一個信號處理程序,做任何你喜歡的。順便提一下,缺省的SIGINT
處理程序只會引發一個KeyboardInterrupt
異常,所以如果您不想使用信號,則可以將整個程序放在try/except結構中,並獲得或多或少的相同效果。由於你想停止主線程在子線程中的任何崩潰,只需將整個while循環放在except Exception:
try-except塊中。
這應該可以工作,但一些背景信息 - Python的信號模塊文檔明確指出,當多個線程正在運行時,只有主線程(即您的進程啓動時創建的線程)將接收信號(對於您而言,它不應該因爲你想要主線程中的信號)。所以信號處理程序將只在一個線程中執行,而不是全部執行。爲了讓所有線程停止響應信號,您需要主線程的信號處理程序將停止消息傳遞給其他子線程。這可以通過不同的方式完成,最簡單的方法是讓主線程翻轉所有子線程持有引用的布爾變量的值。這只是爲了捕獲一個場景,其中一個子線程崩潰並且信號發送到主線程以正常關閉,使用上述方法可以關閉子線程而不會突然終止它們。
有一個線程「控制」它的父母不是一個好習慣。主線程管理/監視/控制它啓動的線程更有意義。
所以我的建議是,你的主線程啓動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
,使其完全退出)。