[Python-ideas] `__iter__` for queues?
Anh Hai Trinh
anh.hai.trinh at gmail.com
Wed Jan 20 06:24:06 CET 2010
> I was thinking of methods like these, for example:
>
> def close(self):
> self.put(sentinel)
> def __iter__(self):
> while True:
> item = self.get()
> if item is sentinel:
> break
> yield item
> raise StopIteration
That would not be thread-safe because your sentinel is only seen once
by a single lucky consumer, other listeners who called iter() will
still execute self.get() and block forever.
The solution I found is to put the sentinel back in the queue so that
other consumers will see it (this use StopIteration as the sentinel):
def _iterqueue(queue):
# Turn a either a threading.Queue or a multiprocessing.queues.SimpleQueue
# into an thread-safe iterator which will exhaust when StopIteration is
# put into it.
while 1:
item = queue.get()
if item is StopIteration:
# Re-broadcast, in case there is another listener blocking on
# queue.get(). That listener will receive StopIteration and
# re-broadcast to the next one in line.
queue.put(StopIteration)
break
else:
yield item
I agree, however, that this should be left out of the stdlib API.
--
// aht
http://blog.onideas.ws
More information about the Python-ideas
mailing list