【问题标题】:What does sys.exit really do with multiple threads?sys.exit 对多线程有什么作用?
【发布时间】:2016-12-12 19:10:47
【问题描述】:

我对 python 中的 sys.exit() 感到非常困惑。 在python documentation 中,它说“从 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 multithreading exit


【解决方案1】:

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

通过引发 SystemExit(status) 退出解释器。

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

【讨论】:

    【解决方案2】:

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

    通常 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 中,将默认值为 Nonedaemon 关键字参数添加到 Thread class constructor 这意味着,从该版本开始,您可以简单地使用:

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

    但是,通过显式属性赋值语句单独执行 仍然有效,因此将是更可移植的方式 这样做。

    【讨论】:

      【解决方案3】:

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

      请阅读这篇文章(:有一个很好的解释如何在你的情况下使用线程 Use of threading.Thread.join()

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

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

      【讨论】:

        猜你喜欢
        • 2013-10-13
        • 2010-10-28
        • 1970-01-01
        • 1970-01-01
        • 2011-04-23
        • 2012-05-14
        • 1970-01-01
        • 2019-04-08
        相关资源
        最近更新 更多