https://docs.python.org/2.7/library/queue.html
def worker():
while True:
item = q.get()
do_work(item)
q.task_done()
q = Queue()
for i in range(num_worker_threads):
t = Thread(target=worker)
t.daemon = True
t.start()
for item in source():
q.put(item)
q.join() # block until all tasks are done
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.
上面这个例子中,同时设置q.join()和t.daemon = True是不是自相矛盾?设置q.join()的话也就是说要等Queue中所有thread发送task_done信号,也就是说要让Queue里面的所有thread全部执行完才继续执行下一步。既然这样的话还设置t.daemon = True干什么呢?t.daemon=True的目的不是让守护进程在后台执行吗?
Setting daemon to True will let the main thread exit even though thworkers are blocking
q.join() Causes the main thread to wait for the queue to finish processing all the tasks
不是。
首先,它不是进程。
其次,「后台」是一个作业控制的术语(命令行 shell 基本都会实现的功能;其它程序基本不理会),就算你这里使用的是多进程,也不适用于你的场景。
最后,这里的设置是有点多余。但是也仅仅是「有点」而已。
多线程是件不容易弄对的事情。信号是另一件。两件加一起,你的 Python 进程不听话啦~(Python 里,信号只会递交给主线程处理。主线程收到信号决定退出,但非 daemon 进程不主动退出的话,进程就会挂在那里。所以我写多线程爬虫什么的时候统一 daemon = True,好 Ctrl-C 的时候能快速停下来。)
对了,大约一两个月之前,python-cn 列表有讨论过 Python daemon 线程的话题,想深入了解的话你可以去围观一下。