线程可以标记为“守护程序线程”。这个的意义 flag是只有守护进程线程时整个Python程序退出 离开了。初始值继承自创建线程。
有没有人更明确地解释这意味着什么或一个实际示例显示您希望将线程设置为daemonic
的位置?
为我澄清:
所以你唯一一次不会将线程设置为守护进程是你希望它们在主线程退出后继续运行吗?
答案 0 :(得分:396)
某些线程执行后台任务,例如发送keepalive数据包,或执行定期垃圾收集等等。这些仅在主程序运行时才有用,并且一旦其他非守护程序线程退出就可以将它们终止。
如果没有守护程序线程,在程序完全退出之前,您必须跟踪它们并告诉它们退出。通过将它们设置为守护程序线程,您可以让它们运行并忘记它们,当程序退出时,任何守护程序线程都会自动终止。
答案 1 :(得分:25)
假设您正在制作某种仪表板小部件。作为此项的一部分,您希望它在您的电子邮箱中显示未读邮件计数。所以你做了一个小线程:
当您的窗口小部件启动时,它将创建此线程,将其指定为守护程序,然后启动它。因为它是一个守护进程,你不必考虑它;当您的小部件退出时,该线程将自动停止。
答案 2 :(得分:14)
考虑它的一种更简单的方法,可能是:当main返回时,如果非守护程序线程仍在运行,则进程将不会退出。
一些建议:当涉及线程和同步时,干净关闭很容易出错 - 如果可以避免,请执行此操作。尽可能使用守护程序线程。
答案 3 :(得分:13)
其他海报为您使用守护程序线程的情况提供了一些示例。但是,我建议永远不要使用它们。
这不是因为它们没用,而是因为如果使用它们会有一些不良副作用。在Python运行时开始拆除主线程中的事情后,守护程序线程仍然可以执行,从而导致一些非常奇怪的异常。
更多信息:
https://joeshaw.org/python-daemon-threads-considered-harmful/
https://mail.python.org/pipermail/python-list/2005-February/343699.html
严格来说,你永远不需要它们,它只是在某些情况下使实施更容易。
答案 4 :(得分:9)
Chris已经解释了守护线程是什么,所以让我们来谈谈实际用法。许多线程池实现为任务工作者使用守护程序线程。工作者是从任务队列执行任务的线程。
工作人员需要无限期地等待任务队列中的任务,因为他们不知道新任务何时出现。分配任务的线程(比如主线程)只知道任务何时结束。主线程等待任务队列变空,然后退出。如果worker是用户线程,即非守护进程,则程序不会终止。即使工人没有做任何有用的工作,它仍会等待这些无限期工作的工人。标记工作人员守护程序线程,主线程将在完成处理任务后立即将其杀死。
答案 5 :(得分:6)
引用Chris:“......当你的程序退出时,任何守护程序线程都会被自动终止。”我认为这总结了一下。使用它们时应该小心,因为它们在主程序执行完毕时突然终止。
答案 6 :(得分:1)
我还将在这里添加我的一些内容,我认为守护线程让大多数人感到困惑的部分原因(至少对我来说是这样)并且不太清楚地理解单词 dameon
的含义。
我的 unix 术语 daemon
指的是在后台生成并保持运行的进程,用户可以通过前台进程转移到其他内容。
在 Python 线程上下文中,每个线程在创建时都在后台运行,无论是 daemon
还是 non-daemon
,区别在于这些线程如何影响主线程。当您拥有 non-daemon
时,您的主线程将在所有此类 non-daemon
线程完成执行后才会退出,因此在某种程度上您的主线程会被这些 non-daemon
线程阻塞。>
对于 daemon
线程,它们仍然在后台运行,但有一个关键区别,即它们不会阻塞主线程,一旦主线程完成并退出,所有 daemon
线程都将被收割。这使得它们对于您想要异步执行的操作很有用,但一旦主应用程序退出,这些操作也应该退出。
需要注意的一点是,您应该清楚自己在 daemon
线程中到底在做什么,它们在主线程退出时退出的事实会给您带来意想不到的惊喜。
关于 daemon
线程的另一件事是 Python 文档中的定义。
这个标志的意义在于整个Python程序退出 当只剩下守护线程时
简单来说,这意味着如果您的程序同时具有 daemon
和 non-daemon
线程,则主程序将被阻塞并等待所有 non-daemon
退出,一旦他们退出主线程也会退出。该声明还暗示但乍一看不清楚的是,一旦主线程退出,所有 daemon
线程将自动退出。
答案 7 :(得分:0)
当第二个线程是非守护程序时,应用程序的主主线程无法退出,因为它的退出条件也与非守护程序线程的退出联系在一起。不能在python中强制杀死线程,因此您的应用程序将必须真正等待非守护进程线程退出。如果这种行为不是您想要的,则将您的第二个线程设置为守护程序,以便它不会阻止您的应用程序退出。