Daemon线程说明

Python文档中 它说:< / p >

线程可以被标记为“守护线程”。这其中的意义 标志表示当只有守护进程线程时,整个Python程序退出 是离开了。初始值继承自创建的线程

有人对这意味着什么有更清楚的解释吗?或者有一个实际的例子说明在哪里将线程设置为daemonic?

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

159189 次浏览

有些线程执行后台任务,比如发送keepalive包,或执行定期垃圾收集,等等。这些线程只在主程序运行时有用,并且可以在其他非守护进程线程退出后将它们删除。

如果没有守护线程,您必须跟踪它们,并在程序完全退出之前告诉它们退出。通过将它们设置为守护线程,您可以让它们运行并忘记它们,当您的程序退出时,任何守护线程都会自动被杀死。

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

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

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

也许可以用一种更简单的方式来考虑:当main返回时,如果有非守护进程线程仍在运行,则您的进程将不会退出。

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

其他帖子给出了一些使用守护进程线程的示例。然而,我的建议是永远不要使用它们。

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

更多信息:

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

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

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

引用克里斯的话:“……当您的程序退出时,所有守护进程线程将自动被杀死。”我想这就是总结。在使用它们时要小心,因为当主程序执行到完成时,它们会突然终止。

Chris已经解释了守护线程是什么,所以让我们讨论一下实际使用。许多线程池实现使用守护线程作为任务工作者。工作线程是执行任务队列中的任务的线程。

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

当第二个线程不是daemon线程时,应用程序的主主线程不能退出,因为它的退出条件也绑定到非daemon线程的退出。在python中线程不能被强制杀死,因此你的应用程序将不得不等待非daemon线程退出。如果这种行为不是您想要的,那么将第二个线程设置为守护进程,这样它就不会阻止应用程序退出。

我还将在这里补充我的一些内容,我认为守护线程对大多数人来说是令人困惑的原因之一(至少对我来说是这样)是因为dameon这个词的Unix上下文。

在Unix术语中,daemon指的是一个进程,它曾经生成;保持在后台运行,用户可以移动到前台进程做其他事情。

在Python线程环境中,创建的每个线程都在后台运行,无论是daemon还是non-daemon,区别在于这些线程如何影响主线程。

当你启动一个non-daemon线程时,它开始在后台运行,你可以执行其他事情,然而,你的主线程不会退出,直到所有这样的non-daemon线程完成它们的执行,所以在某种程度上,你的程序或主线程被阻塞。

daemon线程仍然在后台运行,但有一个关键的区别,它们不会阻塞主线程。 主线程一旦完成执行&当程序退出时,所有剩余的daemon线程将被收割。这使得它们对于那些希望在后台执行但希望这些操作在主应用程序退出时自动退出的操作非常有用

需要注意的一点是,你应该意识到你在daemon线程中到底在做什么,它们在主线程退出时退出的事实可能会给你意想不到的惊喜。优雅地清理daemon线程的方法之一是使用线程的事件将事件设置为退出处理程序,并检查事件是否在线程内部设置,然后相应地从线程函数中断。

关于daemon线程的另一件令人困惑的事情是python文档中的定义。

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

简单地说,这意味着如果你的程序同时有daemonnon-daemon线程,主程序将被阻塞,并等待所有non-daemon线程退出,当它们退出时主线程也将退出。这句话还暗示,但乍一看不清楚的是,所有daemon线程将在主线程退出后自动退出。

创建Daemon线程时:

  • 您需要一个低优先级的线程
  • 你的线程执行特定于后台的任务,更重要的是,
  • 当您希望该线程在所有用户线程完成任务后立即结束时。

Daemon线程服务的一些例子: Java中的垃圾收集,MS Word中的单词计数检查器,介质中的自动保护程序,并行文件下载应用程序中的文件下载计数器等。