我已经使用队列来传递URL以进行下载,但是当在线程中收到队列时,队列会被破坏:
class ThreadedFetch(threading.Thread):
""" docstring for ThreadedFetch
"""
def __init__(self, queue, out_queue):
super(ThreadedFetch, self).__init__()
self.queue = queue
self.outQueue = out_queue
def run(self):
items = self.queue.get()
print items
def main():
for i in xrange(len(args.urls)):
t = ThreadedFetch(queue, out_queue)
t.daemon = True
t.start()
# populate queue with data
for url, saveTo in urls_saveTo.iteritems():
queue.put([url, saveTo, split])
# wait on the queue until everything has been processed
queue.join()
当我执行main时,输出run()
的执行是:
['http://www.nasa.gov/images/content/607800main_kepler1200_1600-1200.jpg', ['http://broadcast.lds.org/churchmusic/MP3/1/2/nowords/271.mp3', None, 3None, 3]
]
虽然预期是
['http://www.nasa.gov/images/content/607800main_kepler1200_1600-1200.jpg', None, 3]
['http://broadcast.lds.org/churchmusic/MP3/1/2/nowords/271.mp3', None, 3]
答案 0 :(得分:1)
所有线程一次打印其数据,结果交错。如果您希望线程在生产代码中显示数据,那么在编写时需要一些方法让它们合作。一个选项是所有屏幕编写者使用的全局锁定,另一个选项是日志记录模块。
答案 1 :(得分:0)
在开始线程之前填充队列。为I / O添加一个锁(因为@tdelaney说 - 线程正在将写入交错到stdout,结果看起来很糟糕)。并将您的run
方法修改为:
lock = threading.Lock()
def run(self):
while True:
try:
items = self.queue.get_nowait()
with lock:
print items
except Queue.Empty:
break
except Exception as err:
pass
self.queue.task_done()
您可能还会发现使用concurrent.futures执行此操作会更容易。 There is a solid example使用返回在线程池中调用的值的方法。