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)
但是,通过显式属性赋值语句单独进行
仍然有效,因此将是版本可移植性更强的方式
正在做。
我真的被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)
但是,通过显式属性赋值语句单独进行 仍然有效,因此将是版本可移植性更强的方式 正在做。