关于python:threading.Thread的setDaemon()方法

setDaemon() method of threading.Thread

我是Python编程的新手,我理解的是一个进程可以是一个守护进程,但是在守护进程模式下是一个线程,我不理解这个用例,我会请求Python专家帮助我理解这个。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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()

当你跑步时,你会

1
2
3
4
5
6
% test.py
0
1
2
3
got here

现在请注意:

1
         t.daemon = True

再次运行它,您将看到脚本打印相同的结果,但挂起。主线程结束(注意,got here已打印),但第二个线程从未完成。

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

请注意,"守护进程线程"与守护进程几乎没有关系。


模块队列已重命名为以python3开头的队列,以更好地反映模块中存在多个队列类(lifo、fifo、priority)的事实。因此,请在使用此示例时进行更改


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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()

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

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

1
2
3
4
5
6
def basic_worker(q):
        while not q.empty():
            item = q.get()
            # do_work(item)
            print(item)
            q.task_done()