为什么在Python线程中调用sys.exit()不退出?
我有点困惑,为什么下面这段代码在线程中调用时不会退出,但在主线程中调用时却会退出。
import sys, time
from threading import Thread
def testexit():
time.sleep(5)
sys.exit()
print "post thread exit"
t = Thread(target = testexit)
t.start()
t.join()
print "pre main exit, post thread exit"
sys.exit()
print "post main exit"
文档里说 sys.exit()
这个调用应该让Python退出。我从这个程序的输出中看到,“线程退出后”的那句话从来没有被打印出来,但主线程在线程调用退出后还是继续运行。
是不是每个线程都创建了一个独立的解释器实例,而调用 exit()
只是退出了那个独立的实例?如果是这样,线程是怎么管理共享资源的访问的呢?如果我真的想从线程中退出程序(虽然我并不想这样,只是为了理解),那该怎么做呢?
6 个回答
如果我想从线程中退出程序怎么办?
除了Deestan提到的方法,你还可以使用 os._exit
(注意有个下划线)。在使用之前,要确保你明白这个方法不会进行任何清理工作(比如不会调用 __del__
或类似的东西)。
如果我想从线程中退出程序怎么办?
对于Linux系统:
os.kill(os.getpid(), signal.SIGINT)
这段代码会向主线程发送一个叫做SIGINT
的信号,这会引发一个KeyboardInterrupt
。虽然这个过程比较复杂,但好处是主线程会按照标准的关闭流程进行清理,比如处理线程、网络连接、文件等,最后执行一些收尾代码。此外,你还可以设置一个处理程序,以便在不同情况下做出反应。
对于Windows系统:
上面的做法在Windows上不管用,因为你只能发送一个SIGTERM
信号,而这个信号Python并不处理,效果和os._exit()
是一样的。
唯一的选择是使用:
os._exit()
这会直接退出整个进程,而不会进行任何清理。如果需要清理,线程就需要通过其他方式与主线程沟通,比如使用队列或者向事件循环发送一个事件。
sys.exit()
会引发一个叫做 SystemExit
的异常,thread.exit()
也是如此。所以,当在某个线程里调用 sys.exit()
时,它引发的这个异常和调用 thread.exit()
的效果是一样的,这就是为什么只有那个线程会退出的原因。