2 回答

TA贡献1877条经验 获得超1个赞
具有“控制”其父线程的线程不是一个好习惯。对于主线程来说,管理/监视/控制它启动的线程更有意义。
因此,我的建议是,您的主线程启动2个线程:您已经拥有的一个线程,该线程在某个时候结束/引发异常,以及一个读取用户输入的线程。现在,主线程等待(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是守护程序,因此我们不必显式使其停止或加入。当主线程退出时,它也会退出。
IMO,无需诉诸信号之类的低级内容。该解决方案甚至不需要使用try-except(尽管您可能会决定要使用try-exceptinThreadA来使其干净退出)。

TA贡献1725条经验 获得超7个赞
Python使您可以通过信号模块访问此系统调用,因此您可以为其注册信号处理程序SIGINT
并执行您喜欢的任何事情。SIGINT
顺便说一句,默认处理程序仅引发KeyboardInterrupt
异常,因此,如果您不想使用信号,则可以将整个程序放在try / except结构中,或多或少获得相同的效果。由于您希望在子线程发生任何崩溃时停止主线程,因此只需将整个while循环放入except Exception:
try-except块中即可。
这应该可以工作,但是需要一些背景信息-Python的信号模块文档明确指出,当多个线程正在运行时,只有主线程(即,在进程启动时创建的线程)将接收信号(对您而言,这无关紧要,因为您想要主线程中的信号)。因此,信号处理程序将仅在一个线程中执行,而不是在所有线程中执行。为了使所有线程都停止响应信号,您需要主线程的信号处理程序将停止消息传递给其他子线程。这可以通过不同的方式完成,最简单的方法是让主线程翻转布尔变量的值,即所有子线程也都拥有引用。
添加回答
举报