假设我有以下代码:
import Queue
import threading
import time
def basic_worker(queue, thread_name):
while True:
if queue.empty(): break
print "Starting %s" % (threading.currentThread().getName()) + "\n"
item = queue.get()
##do_work on item which might take 10-15 minutes to complete
queue.task_done()
print "Ending %s" % (threading.currentThread().getName()) + "\n"
def basic(queue):
# http://docs.python.org/library/queue.html
for i in range(10):
t = threading.Thread(target=basic_worker,args=(queue,tName,))
t.daemon = True
t.start()
queue.join() # block until all tasks are done
print 'got here' + '\n'
queue = Queue.Queue()
for item in range(4):
queue.put(item)
basic(queue)
print "End of program"
我的问题是,如果我设置t.daemon = True
,它会退出代码,杀死需要 10-15 分钟才能在 item 上完成一些工作的线程
从队列中?因为从我读到的内容来看,如果有任何守护线程处于事件状态,程序就会退出。我的理解是,花费很长时间处理该项目的线程也会不完全退出。如果我不设置t.daemon = True
,我的程序将永远挂起,并且当队列中没有项目时不会退出。
最佳答案
如果t.daemon = False
,程序永远挂起的原因是以下代码块...
if queue.empty(): break
...导致竞争条件。
假设队列中只剩下一项,并且两个线程几乎同时评估上述条件。对于两个线程,该条件的计算结果均为False
...因此它们不会中断
。
较快的线程获取最后一个项目,而较慢的线程则永远卡在语句 item = queue.get()
中。
考虑到守护进程模式为False
这一事实,程序将等待所有线程完成。这永远不会发生。
从我的角度来看,您提供的代码(使用 t.daemon = True
)工作正常。
下面这句话可能会让你感到困惑:
The entire Python program exits when no alive non-daemon threads are left.
...但请考虑:如果使用 t.daemon = True 从主线程启动所有线程,则唯一的非守护线程是主线程本身。所以当主线程完成时程序就存在。
...由于 queue.join()
语句,直到队列为空时才会发生这种情况。因此,您在子线程内长时间运行的计算不会被中断。
使用守护线程和queue.join()时,无需检查queue.empty()。
这应该足够了:
#!/bin/python
import Queue
import threading
import time
def basic_worker(queue, thread_name):
print "Starting %s" % (threading.currentThread().getName()) + "\n"
while True:
item = queue.get()
##do_work on item which might take 10-15 minutes to complete
time.sleep(5) # to simulate work
queue.task_done()
def basic(queue):
# http://docs.python.org/library/queue.html
for i in range(10):
print 'enqueuing', i
t = threading.Thread(target=basic_worker, args=(queue, i))
t.daemon = True
t.start()
queue.join() # block until all tasks are done
print 'got here' + '\n'
queue = Queue.Queue()
for item in range(4):
queue.put(item)
basic(queue)
print "End of program"
关于python - 了解 Python 队列并设置线程作为守护线程运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33035027/