Answers:
一些线程执行后台任务,例如发送keepalive数据包,执行定期垃圾回收等。这些仅在主程序正在运行时才有用,并且可以在其他非守护程序线程退出后将其杀死。
如果没有守护程序线程,则必须跟踪它们,并告诉它们退出,然后程序才能完全退出。通过将它们设置为守护程序线程,可以让它们运行并忘记它们,并且在程序退出时,所有守护程序线程都会自动终止。
None
在这种情况下会返回,但没关系,不使用返回值。
其他张贴者提供了一些有关使用守护程序线程的情况的示例。但是,我的建议是永远不要使用它们。
不是因为它们没有用,而是因为如果使用它们,您会遇到一些不良的副作用。在Python运行时开始拆除主线程中的内容之后,守护程序线程仍然可以执行,从而导致一些非常奇怪的异常。
更多信息在这里:
https://joeshaw.org/python-daemon-threads-considered-harmful/
https://mail.python.org/pipermail/python-list/2005-February/343697.html
严格来说,您永远不需要它们,在某些情况下,它只是使实施更容易。
logging
我希望在完成线程后,所有对象(每个线程/函数的文件描述符)都将被销毁。在程序结束时,我看到了许多输出,例如 IOError: [Errno 24] Too many open files:
。使用lsof -p pid_of_program
,我发现FD是打开的,即使Thread / Functions都完成了工作也很困难。解决方法?在函数末尾删除日志处理程序。所以daemonic
线程是不值得信赖的...
克里斯已经解释了什么是守护程序线程,所以让我们谈谈实际用法。许多线程池实现将守护程序线程用于任务工作者。工作者是从任务队列执行任务的线程。
工作人员需要无限期地等待任务队列中的任务,因为他们不知道何时出现新任务。分配任务的线程(例如主线程)仅知道任务何时结束。主线程等待任务队列变空,然后退出。如果worker是用户线程,即非守护程序,则程序不会终止。即使工人没有做任何有用的事情,它将继续等待这些无限期地运转的工人。标记工人守护程序线程,主线程将在处理完任务后立即杀死它们。