如何从Python线程退出整个应用程序?
我如何退出我的整个Python应用程序的一个线程? sys.exit()只会终止它被调用的线程,所以这没有帮助。
我不想使用os.kill()解决scheme,因为这不是很干净。
如果除了主线程之外的所有线程都是守护进程,最好的方法通常是thread.interrupt_main() – 任何线程都可以使用它在主线程中引发KeyboardInterrupt
,通常可以从主线程中合理地清除退出包括主线程中的终结器被调用等)。
当然,如果这会导致一些非守护线程保持整个进程的活跃状态,那么您需要像马克build议的那样使用os._exit
进行后续处理 – 但是我会看到这是最后的手段(类似于kill -9
; – ),因为它非常粗暴地终止了事情(终结器不运行,包括try/finally
块,块, atexit
函数等)。
简短的回答:使用os._exit
。
用例子的长答案:
我从DevShed上的一个教程中抽出一点简单的线程例子,
import threading, sys, os theVar = 1 class MyThread ( threading.Thread ): def run ( self ): global theVar print 'This is thread ' + str ( theVar ) + ' speaking.' print 'Hello and good bye.' theVar = theVar + 1 if theVar == 4: #sys.exit(1) os._exit(1) print '(done)' for x in xrange ( 7 ): MyThread().start()
如果将sys.exit(1)
注释掉,那么脚本将在第三个线程打印出来后死亡。 如果使用sys.exit(1)
并注释掉os._exit(1)
,则第三个线程不会打印(done)
,程序将在所有七个线程中运行。
os._exit
“通常应该只在fork()后面的subprocess中使用 – 并且一个单独的线程足够接近你的目的。 另外请注意,在手册页中os._exit
列出了几个枚举值,您应该将这些值作为os._exit
参数,而不是像上面示例中使用的简单数字。
在某些情况下使用thread.interrupt_main()
可能无济于事。 KeyboardInterrupt
经常在命令行应用程序中用于退出当前命令或清除input行。
另外, os._exit
会立即os._exit
进程,而不会在代码中运行任何finally
块,这可能是危险的(文件和连接不会被closures)。
我find的解决scheme是在主线程中注册一个引发自定义exception的信号处理程序。 使用后台线程来触发信号。
import signal import os import threading import time class ExitCommand(Exception): pass def signal_handler(signal, frame): raise ExitCommand() def thread_job(): time.sleep(5) os.kill(os.getpid(), signal.SIGUSR1) signal.signal(signal.SIGUSR1, signal_handler) threading.Thread(target=thread_job).start() # thread will fire in 5 seconds try: while True: user_input = raw_input('Blocked by raw_input loop ') # do something with 'user_input' except ExitCommand: pass finally: print('finally will still run')
相关问题:
- 为什么在Python中的线程内调用sys.exit()不会退出?
- Python:如果在阻塞raw_input的情况下退出CLI?