273

Python 文档 中它说:

可以将线程标记为“守护线程”。这个标志的意义在于,当只剩下守护线程时,整个 Python 程序就退出了。初始值继承自创建线程。

有没有人对这意味着什么有更清晰的解释,或者有一个实际示例显示您将线程设置为的位置daemonic

为我澄清一下:所以你不会将线程设置为的唯一情况daemonic是,当你希望它们在主线程退出后继续运行时?

4

8 回答 8

509

一些线程执行后台任务,例如发送保活数据包,或执行定期垃圾收集等。这些仅在主程序运行时才有用,一旦其他非守护程序线程退出,就可以将它们杀死。

如果没有守护线程,您必须跟踪它们并告诉它们退出,然后您的程序才能完全退出。通过将它们设置为守护线程,您可以让它们运行并忘记它们,并且当您的程序退出时,所有守护线程都会自动终止。

于 2008-10-10T03:27:36.143 回答
32

假设您正在制作某种仪表板小部件。作为其中的一部分,您希望它在您的邮箱中显示未读邮件计数。所以你做了一个小线程,它将:

  1. 连接到邮件服务器并询问您有多少未读邮件。
  2. 用更新后的计数向 GUI 发出信号。
  3. 睡一会儿。

当您的小部件启动时,它会创建此线程,将其指定为守护进程,然后启动它。因为它是一个守护进程,所以你不必考虑它;当您的小部件退出时,线程将自动停止。

于 2008-10-10T03:36:16.703 回答
19

其他海报给出了一些使用守护线程的例子。但是,我的建议是永远不要使用它们。

这不是因为它们没有用,而是因为如果你使用它们,你会遇到一些不好的副作用。在 Python 运行时开始拆除主线程中的东西后,守护线程仍然可以执行,从而导致一些非常奇怪的异常。

更多信息在这里:

https://joeshaw.org/python-daemon-threads-considered-harmful/

https://mail.python.org/pipermail/python-list/2005-February/343697.html

严格来说,您永远不需要它们,它只是在某些情况下使实施更容易。

于 2009-02-24T22:55:10.797 回答
18

一种更简单的思考方式可能是:当 main 返回时,如果非守护线程仍在运行,您的进程将不会退出。

一点建议:当涉及线程和同步时,干净关闭很容易出错 - 如果可以避免,请这样做。尽可能使用守护线程。

于 2008-10-10T04:34:28.660 回答
12

Chris 已经解释了守护线程是什么,那么让我们来谈谈实际使用。许多线程池实现为任务工作者使用守护线程。工作者是从任务队列执行任务的线程。

Worker 需要无限期地等待任务队列中的任务,因为他们不知道新任务何时会出现。分配任务的线程(比如主线程)只知道任务何时结束。主线程等待任务队列变空然后退出。如果工人是用户线程,即非守护程序,程序将不会终止。它将继续等待这些无限期运行的工人,即使工人没有做任何有用的事情。标记工人守护线程,主线程将在完成处理任务后立即杀死它们。

于 2016-08-27T14:40:41.883 回答
11

引用 Chris:“......当你的程序退出时,任何守护线程都会自动终止。”。我想总结一下。使用它们时应该小心,因为它们会在主程序执行完成时突然终止。

于 2011-08-12T18:14:15.263 回答
7

当您的第二个线程是非守护程序时,您的应用程序的主主线程无法退出,因为它的退出标准也与非守护程序线程的退出相关联。线程不能在 python 中被强行杀死,因此您的应用程序将不得不真正等待非守护线程退出。如果这种行为不是你想要的,那么将你的第二个线程设置为守护进程,这样它就不会阻止你的应用程序退出。

于 2018-07-14T14:27:59.200 回答
6

我还将在这里添加我的一些内容,我认为守护线程让大多数人感到困惑的部分原因(至少对我来说是这样)并且不太清楚理解是这个词的含义dameon

我的unix术语daemon是指在后台产生并保持运行的进程,用户可以通过前台进程继续处理其他内容。

在 Python 线程上下文中,创建时的每个线程都在后台运行,无论是daemon还是non-daemon,不同之处在于这些线程如何影响主线程。当你有一个non-daemon线程时,你的主线程将不会退出,直到所有这些non-daemon线程都完成了它们的执行,所以在某种程度上你的主线程被阻塞了。

对于daemon线程,它们仍然在后台运行,但有一个关键区别是它们不会阻塞主线程,并且一旦主线程完成并退出,所有daemon线程都将被回收。这使得它们对于您想要异步执行的操作很有用,但是一旦主应用程序退出,这些操作也应该退出。

需要注意的一点是,你应该知道你在daemon线程中到底在做什么,当主线程退出时它们退出的事实会给你带来意想不到的惊喜。

对线程感到困惑的另一件事daemon是 python 文档中的定义。

这个标志的意义在于当只剩下守护线程时整个Python程序退出

简而言之,这意味着如果您的程序同时具有线程daemonnon-daemon线程,则主程序将被阻塞并等待所有non-daemon线程退出,一旦它们退出,主线程也将退出。该语句还暗示但乍一看并不清楚的是,daemon一旦主线程退出,所有线程将自动退出。

于 2021-07-28T07:36:26.467 回答