Python 线程/队列挂起问题
新手在这里穿线。在尝试使用线程/队列构建我的第一个脚本时,我从中借用了很多代码:Python 线程/队列挂起问题,python,multithreading,queue,Python,Multithreading,Queue,新手在这里穿线。在尝试使用线程/队列构建我的第一个脚本时,我从中借用了很多代码: import threading, urllib2 import Queue import sys from PIL import Image import io, sys def avhash(url,queue): if not isinstance(url, Image.Image): try: im = Image.open(url) exc
import threading, urllib2
import Queue
import sys
from PIL import Image
import io, sys
def avhash(url,queue):
if not isinstance(url, Image.Image):
try:
im = Image.open(url)
except IOError:
fd=urllib2.urlopen(url)
image_file=io.BytesIO(fd.read())
im=Image.open(image_file)
im = im.resize((8, 8), Image.ANTIALIAS).convert('L')
avg = reduce(lambda x, y: x + y, im.getdata()) / 64.
hash = reduce(lambda x, (y, z): x | (z << y),
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
0)
queue.put({url:hash})
queue.task_done()
def fetch_parallel(job_list):
q = Queue.Queue()
threads = [threading.Thread(target=avhash, args = (job,q)) for job in job_list[0:50]]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
return [q.get() for _ in xrange(len(job_list))]
在本例中,作业列表是URL的列表。我发现当该列表等于或小于50时,该代码可以正常工作,但当>50时,它将挂起。关于线程是如何工作的,肯定有一些我根本不了解的地方?您的问题是这一行:
return [q.get() for _ in xrange(len(job_list))]
若作业列表包含的元素超过50个,那个么您尝试从队列中读取的结果要多于输入的结果。因此:
return [q.get() for _ in xrange(len(job_list[:50]))]
或者,更好的是:
MAX_LEN = 50
...
threads = [... for job in job_list[:MAXLEN]]
...
return [q.get() for _ in job_list[:MAXLEN]]
[编辑]
看起来你希望你的程序做一些不同于它所做的事情。您的程序获取job_列表中的前50个条目,在一个线程中处理每个条目,并忽略所有其他作业。根据您下面的评论,我假设您希望处理所有工作,但一次只处理50个。为此,您应该使用线程池。在Python>=3.2中,可以使用concurrent.futures.ThreadPoolExecutor
在Python<3.2中,您必须自己滚动:
CHUNK_SIZE = 50
def fetch_parallel(job_list):
results = []
queue = Queue.Queue()
while job_list:
threads = [threading.Thread(target=avhash, args=(job, queue))
for job in job_list[:CHUNK_SIZE]]
job_list = job_list[CHUNK_SIZE:]
for thread in threads:
thread.daemon = True
thread.start()
for thread in threads:
thread.join()
results.extend(queue.get() for _ in threads)
return results
未经测试
[/EDIT]您好,代码运行时没有错误,但只返回前50个结果。