sys.exit 对多线程到底做了什么?

What does sys.exit really do with multiple threads?

我真的被python中的sys.exit()弄糊涂了。 在python documentation中,它表示"Exit from Python";这是否意味着在 python 程序中调用 sys.exit() 时,进程将退出?如果是这样,下面的代码会显示不同的结果:

import sys
import time
import threading

def threadrun():
    while(True):
        time.sleep(1)

if __name__=="__main__":
    t=threading.Thread(target=threadrun)
    t.start()
    sys.exit()

在 linux 中启动此程序,结果不是 python 文档中所说的预期结果,但系统中仍然 运行,那么 sys.exit() 到底做了什么?

在您的情况下,程序结束是最后一个线程终止的时间。也许 python 中的某种 join() 方法(如 Java 中的)将等待其他线程。

请阅读这篇文章(:在您的案例中很好地解释了如何使用线程 Use of threading.Thread.join()

文档 https://docs.python.org/2/library/threading.html(不过放心,这只是为了补充知识。

并阅读这篇关于守护进程的文章 属性(如果您不想等待其他线程终止 Meaning of daemon property on Python Threads

根据文档 sys.exit() 提出 SystemExit:

Exit the interpreter by raising SystemExit(status).

如果 SystemExit 达到 default exception handler, 它调用 handle_system_exit(),它或多或少地推到 Python 2 中的 Py_Finalize(), which in turn calls wait_for_thread_shutdown(),因此 sys.exit() 与正常的 从底部掉落相同主模块 正在等待所有非守护线程终止。

(解释 Python 2 文档中 Thread Objects 的内容)

通常 Python 程序只有在只有守护进程时才会退出 线程(忽略自身)离开 运行。对应于程序中初始控制线程的“主线程”对象不是守护线程。使用 threading.Thread 创建的线程从创建线程继承它们的守护进程状态,因此如果这是主线程,它们也将是非守护进程。

这意味着 默认情况下 主程序创建和启动的任何线程将阻止主程序退出,如果它们仍然 运行 当主线程终止时(通过 sys.exit() 或只是点击其代码的末尾)。换句话说,程序仅在没有 非守护进程 线程(即只有守护线程)时退出。

您可以通过显式设置✶✶来覆盖此默认行为 daemon 属性 任意 在 启动它之前 True 创建了线程对象。

if __name__=="__main__":
    t = threading.Thread(target=threadrun)
    t.daemon = True  # Explicitly set property.
    t.start()
    sys.exit()

这将允许程序在 sys.exit() 被调用时真正结束(尽管像那样显式调用它是没有必要的,因为上面的代码可能无论如何都会在脚本的末尾)。


守护线程是在后台运行并且不会阻止解释器退出的线程。参见 Daemon Threads Explanation

✶✶ 在 Python 3.3 中,daemon 关键字参数的默认值为 None 已添加到 Thread class constructor 这意味着,从该版本开始,您可以简单地使用:

    # Sets whether the thread is daemonic via "daemon" keyword argument.
    t = threading.Thread(target=threadrun, daemon=True)

但是,通过显式属性赋值语句单独进行 仍然有效,因此将是版本可移植性更强的方式 正在做。