【发布时间】:2010-04-16 01:38:01
【问题描述】:
假设我被困在使用 Python 2.6 并且无法升级(即使这会有所帮助)。我编写了一个使用 Queue 类的程序。我的制作人是一个简单的目录列表。我的消费者线程从队列中拉出一个文件,并用它做一些事情。如果文件已经被处理,我跳过它。处理的列表是在所有线程启动之前生成的,所以它不是空的。
这是一些伪代码。
import Queue, sys, threading
processed = []
def consumer():
while True:
file = dirlist.get(block=True)
if file in processed:
print "Ignoring %s" % file
else:
# do stuff here
dirlist.task_done()
dirlist = Queue.Queue()
for f in os.listdir("/some/dir"):
dirlist.put(f)
max_threads = 8
for i in range(max_threads):
thr = Thread(target=consumer)
thr.start()
dirlist.join()
我得到的奇怪行为是,如果一个线程遇到一个已经被处理的文件,该线程就会停止并等待整个程序结束。我做了一些测试,前 7 个线程(假设 8 个是最大值)停止,而第 8 个线程继续处理,一次一个文件。但是,这样一来,我就失去了对应用程序进行线程化的全部理由。
我做错了什么,或者这是 Python 2.6 中队列/线程类的预期行为?
【问题讨论】:
-
肯定有什么问题——为什么会预期依赖于与队列完全无关的测试?!但是我不认为它在这个代码中,尽管它有缺陷(线程不是守护进程,滥用内置名称
file,...)——我认为这些不会使线程停止!相反,如何处理填充,并且它是否在“...”部分进行了更改(这可能是一个问题,因为它周围没有锁定)?你能用微不足道的处理人口(例如把一半的文件放在那里)和微不足道的“...”来重现这个问题吗?例如print file?
标签: python multithreading queue