2 回答

TA貢獻(xiàn)1877條經(jīng)驗 獲得超1個贊
具有“控制”其父線程的線程不是一個好習(xí)慣。對于主線程來說,管理/監(jiān)視/控制它啟動的線程更有意義。
因此,我的建議是,您的主線程啟動2個線程:您已經(jīng)擁有的一個線程,該線程在某個時候結(jié)束/引發(fā)異常,以及一個讀取用戶輸入的線程?,F(xiàn)在,主線程等待(joins)前者完成,并在完成后退出。
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是守護(hù)程序,因此我們不必顯式使其停止或加入。當(dāng)主線程退出時,它也會退出。
IMO,無需訴諸信號之類的低級內(nèi)容。該解決方案甚至不需要使用try-except(盡管您可能會決定要使用try-exceptinThreadA來使其干凈退出)。

TA貢獻(xiàn)1725條經(jīng)驗 獲得超8個贊
Python使您可以通過信號模塊訪問此系統(tǒng)調(diào)用,因此您可以為其注冊信號處理程序SIGINT
并執(zhí)行您喜歡的任何事情。SIGINT
順便說一句,默認(rèn)處理程序僅引發(fā)KeyboardInterrupt
異常,因此,如果您不想使用信號,則可以將整個程序放在try / except結(jié)構(gòu)中,或多或少獲得相同的效果。由于您希望在子線程發(fā)生任何崩潰時停止主線程,因此只需將整個while循環(huán)放入except Exception:
try-except塊中即可。
這應(yīng)該可以工作,但是需要一些背景信息-Python的信號模塊文檔明確指出,當(dāng)多個線程正在運(yùn)行時,只有主線程(即,在進(jìn)程啟動時創(chuàng)建的線程)將接收信號(對您而言,這無關(guān)緊要,因為您想要主線程中的信號)。因此,信號處理程序?qū)H在一個線程中執(zhí)行,而不是在所有線程中執(zhí)行。為了使所有線程都停止響應(yīng)信號,您需要主線程的信號處理程序?qū)⑼V瓜鬟f給其他子線程。這可以通過不同的方式完成,最簡單的方法是讓主線程翻轉(zhuǎn)布爾變量的值,即所有子線程也都擁有引用。
添加回答
舉報