【问题标题】:setDaemon() method of threading.Threadthreading.Thread 的 setDaemon() 方法
【发布时间】:2011-02-26 14:22:12
【问题描述】:

我是python编程的新手,我的理解是一个进程可以是一个守护进程,但是一个守护进程模式下的线程,我无法理解这个用例,我会请求python大师帮助我在理解这一点。

【问题讨论】:

  • 最好的答案是stackoverflow.com/a/190017/260122
  • hue:threading 文档说不要使用旧的 setDaemon() 方法(尽管它没有说它已弃用)。
  • 它并不老,当你创建线程作为参数时,它已作为一个选项添加,所以现在你不必使用 setter。 class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

标签: python multithreading


【解决方案1】:

下面是一些使用线程的基本代码:

import Queue
import threading

def basic_worker(queue):
    while True:
        item = queue.get()
        # do_work(item)
        print(item)
        queue.task_done()
def basic():
    # http://docs.python.org/library/queue.html
    queue = Queue.Queue()
    for i in range(3):
         t = threading.Thread(target=basic_worker,args=(queue,))
         t.daemon = True
         t.start()
    for item in range(4):
        queue.put(item)
    queue.join()       # block until all tasks are done
    print('got here')

basic()

当你运行它时,你会得到

% test.py
0
1
2
3
got here

现在注释掉这一行:

         t.daemon = True

再次运行,您会看到脚本打印相同的结果,但挂起。 主线程结束(注意打印了got here),但第二个线程永远不会结束。

相反,当t.daemon设置为True时,线程t在主线程结束时终止。

请注意,“守护线程”与daemon processes 关系不大。

【讨论】:

  • 应该是 t.SetDaemon(True) 吗?
  • @GreenAsJade:t.setDaemon(True) 是旧 API 的一部分。如今,t.daemon = True 是使t 成为守护线程的推荐方式。
  • 但是当它“与daemon processes无关”时,为什么它被称为“守护线程”。
【解决方案2】:

看起来人们打算使用 Queue 来解释线程,但我认为应该有更简单的方法,使用 time.sleep() 来演示守护线程。

通过设置daemon参数(默认为None)创建守护线程:

from threading import Thread
import time

def worker():
    time.sleep(3)
    print('daemon done')

thread = Thread(target=worker, daemon=True)
thread.start()

print('main done')

输出:

main done

Process finished with exit code 0

删除守护进程参数,如:

thread = Thread(target=worker)

重新运行并查看输出:

main done
daemon done

Process finished with exit code 0

这里我们已经看到了守护线程的区别:

如果只剩下守护线程,整个 Python 程序就可以退出。


isDaemon()setDaemon() 是旧的 getter/setter API。建议使用构造函数参数,如上,或daemon 属性。

【讨论】:

    【解决方案3】:

    从 Python3 开始,Module Queue 已重命名为 queue,以更好地反映模块中有多个队列类(lifo、fifo、priority)的事实。 所以请在使用此示例时进行更改

    【讨论】:

      【解决方案4】:

      我已经为 python 3 改编了@unutbu 的答案。确保从命令行运行这个脚本,而不是像 jupyter notebook 这样的交互式环境。

      import queue
      import threading
      
      
      def basic_worker(q):
          while True:
              item = q.get()
              # do_work(item)
              print(item)
              q.task_done()
      
      
      def basic():    
          q = queue.Queue()
          for item in range(4):
              q.put(item)    
      
          for i in range(3):
               t = threading.Thread(target=basic_worker,args=(q,))
               t.daemon = True
               t.start()
      
          q.join()       # block until all tasks are done
          print('got here')
      
      basic()
      

      因此,当您注释掉 daemon 行时,您会注意到程序没有完成,您必须手动中断它。 将线程设置为守护线程可确保它们在完成后被杀死。

      注意:如果您将无限 while 循环替换为另一个条件,您可以在没有守护线程的情况下在这里实现相同的效果:

      def basic_worker(q):
              while not q.empty():
                  item = q.get()
                  # do_work(item)
                  print(item)
                  q.task_done()
      

      【讨论】:

      • 使Threads 成为守护进程并不能确保它们一旦完成就被杀死——它允许它们被杀死,无论它们是否完成。为确保完成,您需要调用其join() 方法。
      【解决方案5】:

      简单来说...

      什么是守护线程?

      • 守护线程可以在它们的流程之间随时关闭 非守护线程 (即用户线程)完全执行
      • 守护线程在其他非守护线程运行时在后台间歇运行
      • 当所有非守护线程完成后,守护线程会自动终止(无论它们是否被完全执行) .
      • 守护线程服务提供者,用于在同一进程中运行的用户线程
      • python 不关心 守护线程运行状态 时完成,甚至不关心 finally 块 但是 python 确实优先考虑我们创建的非守护线程
      • 守护线程在操作系统中充当服务。
      • 当所有用户线程(与守护线程相反)终止时,python会停止守护线程。因此,守护线程可用于实现,例如,当线程被python停止时,所有用户线程已停止。

      简而言之

      如果你这样做

      thread = Thread(target=worker_method, daemon=True)
      

      不保证worker_method 将被完全执行。

      这种行为有什么用处?

      考虑两个线程t1(父线程)t2(子线程)。让t2 成为守护进程。现在,您要分析t1 在运行状态下的工作情况;您可以在t2 中编写代码来执行此操作。

      参考:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 2018-08-13
        • 1970-01-01
        相关资源
        最近更新 更多