守护程序线程说明

Cor*_*erg 227 python multithreading daemon python-multithreading

Python文档中 它说:

线程可以标记为"守护程序线程".这个标志的意义在于,当只剩下守护进程线程时,整个Python程序都会退出.初始值继承自创建线程.

有没有人更明确地解释这意味着什么或一个实际的例子显示你想要将线程设置为何处daemonic


为我澄清一下:

因此,如果您希望它们在主线程退出后继续运行,那么您唯一不会将线程设置为守护程序的时间是?

Chr*_*ung 424

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

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

  • @san写作完成后你的作家线程做了什么?它刚回来了吗?如果是这样,那就足够了.守护程序线程通常用于循环中运行的东西,而不是自己退出. (6认同)
  • 因此,如果我有一个正在执行设置为非守护进程的文件写入操作的子线程,这是否意味着我必须使其显式退出? (2认同)
  • @san 如果它从线程函数的底部掉下来,它会隐式返回。 (2认同)

Joh*_*uhy 26

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

  1. 连接到邮件服务器,询问您有多少条未读邮件.
  2. 使用更新的计数向GUI发送信号.
  3. 睡了一会儿.

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


Roh*_*hit 22

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

在 Unix 术语中,这个词daemon指的是曾经产生的进程;保持在后台运行,用户可以继续在前台进程中执行其他操作。

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

当您启动一个线程时,它开始在后台运行,您可以执行其他操作,但是,直到所有此类线程完成执行后,您的non-daemon主线程才会退出,因此在某种程度上,您的程序或主线程被阻塞。non-daemon

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

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

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

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

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

  • 我喜欢你如何解释“守护进程”的含义。这正是我想要的。 (4认同)

Joe*_*haw 15

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

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

更多信息:

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

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

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

  • 来自Joe的博客文章:"2015年6月更新:这是[Python bug 1856](http://bugs.python.org/issue1856).它已在Python 3.2.1和3.3中修复,但修复程序从未向后移植到2 .x.(尝试向后移植到2.7分支导致另一个错误并且它被放弃了.)守护程序线程在Python> = 3.2.1中可能没问题,但绝对不是早期版本." (4认同)

Jon*_*han 14

考虑它的一种更简单的方法,可能是:当main返回时,如果仍存在非守护程序线程,则进程将不会退出.

一些建议:当涉及线程和同步时,干净关闭很容易出错 - 如果可以避免,请执行此操作.尽可能使用守护程序线程.


Ami*_*mit 10

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

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

  • 小心点!如果程序提交一个_重要_任务(例如,“在后台”更新某个文件)到守护进程任务队列,那么程序可能会在执行任务之前终止,或者更糟的是,在更新该文件的过程中终止。 (5认同)

Bas*_*ass 7

引用克里斯:"......当你的程序退出时,任何守护程序线程都会自动被杀死." 我认为这总结了一下.使用它们时应该小心,因为它们在主程序执行完成时突然终止.


typ*_*gic 7

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