关于python:守护进程线程说明

Daemon Threads Explanation

在python文档中它说:

A thread can be flagged as a"daemon thread". The significance of this
flag is that the entire Python program exits when only daemon threads
are left. The initial value is inherited from the creating thread.

是否有人对这意味着什么有更清楚的解释,或者有一个实际的例子显示您希望在哪里将线程设置为daemonic

为我澄清:

所以,唯一一次不将线程设置为daemonic是希望它们在主线程退出后继续运行吗?


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

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


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

  • 连接到邮件服务器,询问您有多少封未读邮件。
  • 向GUI发送更新计数的信号。
  • 睡一会儿。
  • 当小部件启动时,它会创建这个线程,将其指定为守护进程,然后启动它。因为它是一个守护进程,所以您不必考虑它;当小部件退出时,线程将自动停止。


    其他的海报为您使用守护进程线程的情况提供了一些示例。不过,我的建议是永远不要使用它们。

    这不是因为它们没有用处,而是因为如果你使用它们,你会遇到一些不良的副作用。守护进程线程仍然可以在Python运行时开始分解主线程中的内容后执行,这会导致一些非常奇怪的异常。

    更多信息在这里:

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

    https://mail.python.org/pipermail/python-list/2005-2月/343699.html

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


    考虑这个问题的一个简单方法是:当main返回时,如果仍有非守护进程线程在运行,那么您的进程将不会退出。

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


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

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


    引用克里斯的话:"…当程序退出时,任何守护进程线程都会自动终止。"。我想这就是总结。当您使用它们时应该小心,因为它们在主程序执行到完成时会突然终止。


    当第二个线程是非守护进程时,应用程序的主线程无法退出,因为它的退出条件也与非守护进程线程的退出相关联。线程不能在python中强制终止,因此您的应用程序必须等待非守护进程线程退出。如果这个行为不是您想要的,那么将您的第二个线程设置为守护进程,这样它就不会阻止您的应用程序退出。