Python可迭代队列

时间:2012-07-02 05:26:46

标签: python queue iteration

我需要知道何时关闭队列并且不会有更多项目,所以我可以结束迭代。

我是通过在队列中放置一个标记来实现的:

from Queue import Queue

class IterableQueue(Queue): 

    _sentinel = object()

    def __iter__(self):
        return self

    def close(self):
        self.put(self._sentinel)

    def next(self):
        item = self.get()
        if item is self._sentinel:
            raise StopIteration
        else:
            return item

鉴于这是一个非常常见的队列使用,是不是有任何内置实现?

2 个答案:

答案 0 :(得分:12)

生成器是一种合理的方式,可以让生产者发送不再有队列任务的消息。

FWIW,您的代码可以使用iter()的两个参数形式进行简化:

from Queue import Queue

class IterableQueue(Queue): 

    _sentinel = object()

    def __iter__(self):
        return iter(self.get, self._sentinel)

    def close(self):
        self.put(self._sentinel)

答案 1 :(得分:4)

多处理模块有自己的Queue版本,其中包含close方法。我不确定它在线程中是如何工作的,但值得一试。我不明白为什么不应该这样做:

from multiprocessing import Queue

q = Queue()
q.put(1)
q.get_nowait()
# 1
q.close()
q.get_nowait()
# ...
# IOError: handle out of range in select()

您可以将IOError作为关闭信号捕获。

<强> TEST

from multiprocessing import Queue
from threading import Thread

def worker(q):
    while True:
        try:
            item = q.get(timeout=.5)
        except IOError:
            print "Queue closed. Exiting thread."
            return
        except:
            continue
        print "Got item:", item

q = Queue()
for i in xrange(3):
    q.put(i)
t = Thread(target=worker, args=(q,))
t.start()
# Got item: 0
# Got item: 1
# Got item: 2
q.close()
# Queue closed. Exiting thread.

虽然说实话,但它与在Queue.Queue上设置标志没什么不同。 multiprocessing.Queue只是使用一个封闭的文件描述符作为标志:

from Queue import Queue

def worker2(q):
    while True:
        if q.closed:
            print "Queue closed. Exiting thread."
            return
        try:
            item = q.get(timeout=.5)
        except:
            continue
        print "Got item:", item

q = Queue()
q.closed = False
for i in xrange(3):
    q.put(i)
t = Thread(target=worker2, args=(q,))
t.start()
# Got item: 0
# Got item: 1
# Got item: 2
q.closed = True
# Queue closed. Exiting thread.