为什么队列显示不正确的数据?

时间:2014-07-12 13:20:42

标签: python queue blockingqueue

我已经使用队列来传递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]

2 个答案:

答案 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使用返回在线程池中调用的值的方法。