在Python文档中上面写着:
线程可以标记为"守护进程线程"。这一点的意义标志是整个Python程序在只有后台进程线程时退出剩下的。初始值是从创建线程继承的。
有人对这意味着什么有更清楚的解释吗?或者有一个实际的例子显示在哪里可以将线程设置为daemonic
吗?
请为我澄清一下:因此,您唯一不会将线程设置为daemonic
的情况是,当您希望它们在主线程退出后继续运行时?
一些线程执行后台任务,如发送保活数据包,或执行定期垃圾收集,或其他任何任务。这些只有在主程序运行时才有用,一旦其他非守护进程线程退出,就可以将它们终止。
如果没有守护进程线程,您必须跟踪它们,并告诉它们退出,然后程序才能完全退出。通过将它们设置为守护进程线程,您可以让它们运行并忘记它们,当您的程序退出时,任何守护进程线程都会自动终止。
假设您正在制作某种仪表板小部件。作为其中的一部分,您希望它在您的电子邮件框中显示未读邮件数。所以你制作了一个小线程:
- 连接到邮件服务器,询问您有多少未读邮件
- 用更新的计数向GUI发出信号
- 睡一会儿
当你的小部件启动时,它会创建这个线程,指定它为守护进程,然后启动它。因为它是一个守护进程,所以你不必考虑它;当您的小部件退出时,线程将自动停止。
一种更简单的思考方式可能是:当main返回时,如果有非守护进程线程仍在运行,则进程将不会退出。
一点建议:当涉及线程和同步时,干净关闭很容易出错——如果可以避免的话,就这样做。尽可能使用守护进程线程。
其他海报为您使用守护进程线程的情况提供了一些示例。然而,我的建议是永远不要使用它们。
这并不是因为它们没有用处,而是因为如果你使用它们,你会经历一些不良的副作用。在Python运行时开始拆除主线程中的东西后,守护程序线程仍然可以执行,这会导致一些非常奇怪的异常。
更多信息请点击此处:
https://joeshaw.org/python-daemon-threads-considered-harmful/
https://mail.python.org/pipermail/python-list/2005-February/343697.html
严格地说,你从来都不需要它们,在某些情况下,它只会让实现变得更容易。
我也会在这里添加我的一些内容,我认为守护进程线程让大多数人感到困惑(至少对我来说是这样)的原因之一是因为单词dameon
的Unix上下文。
在Unix术语中,单词daemon
指的是一个曾经产生的进程;保持在后台运行,用户可以继续使用前台进程做其他事情。
在Python线程上下文中,创建时的每个线程都在后台运行,无论是daemon
还是non-daemon
,不同之处在于这些线程如何影响主线程。
当你启动一个non-daemon
线程时,它开始在后台运行,你可以执行其他事情,但是,在所有这样的non-daemon
线程完成执行之前,你的主线程不会退出,所以在某种程度上,你的程序或主线程被阻止了。
对于daemon
线程,它们仍然在后台运行,但有一个关键区别,即它们不会阻塞主线程。一旦主线程完成其执行&程序退出,所有剩余的daemon
线程将被收获。这使得它们对于您希望在后台执行但希望这些操作在主应用程序退出后立即自动退出的操作非常有用。
需要注意的一点是,您应该知道您在daemon
线程中到底在做什么,当主线程退出时,它们会退出,这可能会给您带来意想不到的惊喜。优雅地清理daemon
线程的方法之一是使用线程事件将事件设置为退出处理程序,并检查该事件是否设置在线程内部,然后相应地中断线程函数。
daemon
线程的另一个困惑是python文档中的定义。
这个标志的意义在于整个Python程序退出当只剩下后台进程线程时
简单地说,这意味着如果您的程序同时具有daemon
和non-daemon
线程,则主程序将被阻止,并等待所有non-daemon
退出,一旦它们退出,主线程也将退出。这句话还意味着,但乍一看并不清楚的是,一旦主线程退出,所有daemon
线程都将自动退出。
引用Chris的话:"…当你的程序退出时,任何守护进程线程都会自动终止。"我认为这就是总结。使用它们时应该小心,因为当主程序执行到完成时,它们会突然终止。
Chris已经解释了什么是守护进程线程,所以让我们谈谈实际用法。许多线程池实现为任务工作者使用守护进程线程。工作线程是执行任务队列中任务的线程。
工作人员需要无限期地等待任务队列中的任务,因为他们不知道新任务何时出现。分配任务的线程(比如主线程)只知道任务何时结束。主线程等待任务队列变空,然后退出。若工作线程是用户线程,即非守护进程,则程序不会终止。它将继续等待这些无限期运转的工人,即使工人们没有做任何有用的事情。标记worker守护进程线程,主线程将在处理完任务后立即杀死它们。
当您的第二个线程是非守护进程时,应用程序的主主线程不能退出,因为它的退出条件也与非守护进程线程的退出绑定。线程不能在python中被强制杀死,因此您的应用程序将不得不真正等待非守护程序线程退出。如果这种行为不是您想要的,那么将您的第二个线程设置为守护进程,这样它就不会阻止您的应用程序退出。
在以下情况下创建守护程序线程:
- 您想要一个低优先级线程
- 您的线程执行特定于背景的任务,更重要的是
- 当您希望在所有用户线程完成任务后立即终止此线程时
守护程序线程服务的一些示例:Java中的垃圾收集、MS Word中的字数检查器、介质中的自动保护程序、并行文件下载应用程序中的文件下载计数器等。