Python线程中的守护进程属性含义

82

我对将线程设置为守护进程(daemon)的含义有点困惑。

文档中这样描述:

线程可以被标记为“守护进程”。这个标志的意义在于,当只剩下守护进程时,整个Python程序就会退出。初始值从创建线程继承而来。可以通过daemon属性设置这个标志。

我不太确定这与普通线程有什么不同。

这是在说这个程序永远不会结束吗?

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

threading.Thread(target=threadfunc).start()

即使主线程执行完毕,while循环会立即结束吗?

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

th = threading.Thread(target=threadfunc)
th.daemon = True
th.start()

我询问这个问题是因为在我的主线程中调用了sys.exit(),但进程一直挂起,而且我可以看到日志中其他线程正在运行。

这是否与在有活动线程的情况下调用sys.exit() 有关?


1
可能是守护线程解释的重复。 - Mr_and_Mrs_D
我可以将daemon=True解释为“此线程作为主线程的守护进程”吗? - jtcloud
3个回答

55

这是在说这个程序永远都不会结束吗?

是的,这个程序永远不会结束,可以试一下。

我问这个是因为我遇到了一个情况,在我的主线程中我调用了sys.exit(),然而进程却一直挂着,其他的线程在运行,我能从日志中看到。这和sys.exit()被调用时还有线程存在有关系吗?

是的,即使使用exit也无法停止其他线程,它只是在主线程中引发SystemExit异常。因此,虽然主线程将停止(就像处理任何其他未处理异常一样),但所有其他非守护线程仍将继续工作。


好的,但是有没有一种方法可以让我的程序在线程运行时退出,并仍然调用atexit()钩子? - Falmarri
@Falmarri:atexit 与此有什么关系?要么将您的线程转换为守护进程,要么编写关闭它们的代码,然后您的程序可以退出(我想调用退出函数)。 - Jochen Ritzel
我正在尝试破解一些代码以进行调试。我不能更改线程等内容。我想我必须寻找另一个解决方案。 - Falmarri
1
文档(https://docs.python.org/3/library/threading.html#thread-objects)中说:“守护线程在关闭时会被突然停止。” - 这难道不意味着当主程序完成时,守护线程也会被关闭吗? - variable

22

设置thread.daemon = True将允许主程序退出。 应用程序通常在完成所有子线程之前等待。


1
但是,如果您不使用join(),那么线程可能会并行运行,就像僵尸进程一样...因此,守护进程选项应与join()一起使用。不这样做吗? - m3nda
6
@erm3nda,这并不完全正确。使用Thread时没有额外的process。请记住,如果没有其他措施,所有Python程序都是单个进程。.join()将阻塞调用范围,直到Thread结束,当然,如果Thread永远不会结束,这可能是一个问题。将一个Thread配置为守护线程只是告诉父线程在需要时杀死它,而不是在父线程希望退出时隐式地.join()。我刚刚学到这个知识,只是几秒钟前,由于某种原因,对我来说非常反直觉。 - John Carrell
感谢 @JohnCarrell - m3nda
文档(https://docs.python.org/3/library/threading.html#thread-objects)中说:“守护线程在关闭时会被突然停止。” - 这难道不意味着当主程序完成时,守护线程也会被关闭吗? - variable

7
th.daemon = True #set this thread as a Daemon Thread

你可以将守护线程看作是一项服务,这意味着它将在计算机的后台运行执行各种任务,如索引文件、解析xml、检索新闻等,任何长时间运行的进程都可以。你的主线程将会结束,但你的守护线程仍将在后台运行,这就是为什么你的程序(即主线程)会结束的原因。如果你想让它继续运行,只需放置一个无限循环即可。垃圾回收就是守护线程的一个例子。

5
你的主线程将会结束,但是你的守护进程仍然会在后台运行。这不正是当线程不是守护进程时的情况吗? - Jeppe
你是说如果任何线程正在执行 while true: 函数,那么它就是前台线程,而不是守护线程? - y_159

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接