2013-05-11 170 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,使其完全退出)。