generators shared among threads
Kent Johnson
kent at kentsjohnson.com
Wed Mar 8 06:05:26 EST 2006
Paul Rubin wrote:
> Hmm (untested, like above):
>
> class Synchronized:
> def __init__(self, generator):
> self.gen = generator
> self.lock = threading.Lock()
> def next(self):
> self.lock.acquire()
> try:
> yield self.gen.next()
> finally:
> self.lock.release()
>
> synchronized_counter = Synchronized(itertools.count())
>
> That isn't a general solution but can be convenient (if I didn't mess
> it up). Maybe there's a more general recipe somewhere.
This code is not allowed in Python 2.4. From PEP 255:
Restriction: A yield statement is not allowed in the try clause of a
try/finally construct. The difficulty is that there's no guarantee
the generator will ever be resumed, hence no guarantee that the finally
block will ever get executed; that's too much a violation of finally's
purpose to bear.
Even if this was allowed, ISTM the semantics might be the same as your
previous attempt - I would expect the finally to be executed after the
yield returns, meaning the lock would be held during the yield.
Python 2.5 will allow this (see PEP 342) but from the examples it seems
the finally won't execute until the yield returns.
Kent
More information about the Python-list
mailing list