Re: generators shared among threads

2006-03-13 Thread Tim Peters
[Paul Rubin] > It looks to me like you can't have two threads in the same generator: You can't even have one thread in a generator-iterator get away with activating the generator-iterator while it's already active. That's an example in PEP 255: """ Restriction: A generator cannot be resumed w

Re: generators shared among threads

2006-03-12 Thread Paul Rubin
Bryan Olson <[EMAIL PROTECTED]> writes: > I have not found definitive answers in the Python doc. Both > generators and threads keep their own line-of-control, and > how they interact is not clear. It looks to me like you can't have two threads in the same generator: import threading, time

Re: generators shared among threads

2006-03-10 Thread Bryan Olson
[EMAIL PROTECTED] wrote: > You'll get the same result without the lock. I'm not sure what this > indicates. It may show that the contention on the lock and the race > condition on i aren't always problems. It may show that generators, at > least in CPython 2.4, provide thread safety for free. I

Re: generators shared among threads

2006-03-09 Thread jess . austin
Bryan, You'll get the same result without the lock. I'm not sure what this indicates. It may show that the contention on the lock and the race condition on i aren't always problems. It may show that generators, at least in CPython 2.4, provide thread safety for free. It does seem to disprove m

Re: generators shared among threads

2006-03-08 Thread jess . austin
I just noticed, if you don't define maxsize in _init(), you need to override _full() as well: def _full(self): return False cheers, Jess -- http://mail.python.org/mailman/listinfo/python-list

Re: generators shared among threads

2006-03-08 Thread Bryan Olson
[EMAIL PROTECTED] wrote: > Paul wrote: > >> def f(): >> lock = threading.Lock() >> i = 0 >> while True: >> lock.acquire() >> yield i >> i += 1 >> lock.release() >> >>but it's easy to make mistakes when implementing things like that >>(I'm

Re: generators shared among threads

2006-03-08 Thread Paul Rubin
[EMAIL PROTECTED] (Alex Martelli) writes: > Now, x=ReentrantIterator(itertools.count()) should have all the > properties we want, I think. The locking is thanks of Queue.Queue and > its sweet implementation of the Template Method design pattern. That is very cool, and generally useful enough that

Re: generators shared among threads

2006-03-08 Thread Just
In article <[EMAIL PROTECTED]>, Kent Johnson <[EMAIL PROTECTED]> wrote: > Paul Rubin wrote: > > Hmm (untested, like above): > > > > class Synchronized: > >def __init__(self, generator): > > self.gen = generator > > self.lock = threading.Lock() > >def next(

Re: generators shared among threads

2006-03-08 Thread Kent Johnson
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

Re: generators shared among threads

2006-03-07 Thread Alex Martelli
Paul Rubin wrote: > [EMAIL PROTECTED] writes: > > The main problem with this is that the yield leaves the lock locked. > > If any other thread wants to read the generator it will block. > > Ouch, good catch. Do you see a good fix other than try/finally? > Is there a c

Re: generators shared among threads

2006-03-07 Thread Paul Rubin
[EMAIL PROTECTED] writes: > The main problem with this is that the yield leaves the lock locked. > If any other thread wants to read the generator it will block. Ouch, good catch. Do you see a good fix other than try/finally? Is there a classical way to do it with coroutines and semaphores? --

Re: generators shared among threads

2006-03-07 Thread jess . austin
Paul wrote: >def f(): >lock = threading.Lock() >i = 0 >while True: >lock.acquire() >yield i >i += 1 >lock.release() > > but it's easy to make mistakes when implementing things like that > (I'm not even totally confident tha

Re: generators shared among threads

2006-03-07 Thread Paul Rubin
[EMAIL PROTECTED] (Alex Martelli) writes: > > g=itertools.count() > > I believe that in the current implementation you'd get "lucky", but > there is no guarantee that such luck would persist across even a minor > bugfix in the implementation. Don't do it. I remember being told that xrange(sys.ma

Re: generators shared among threads

2006-03-07 Thread jess . austin
Alex wrote: > Last, I'm not sure I'd think of this as a reentrantQueue, so > much as a ReentrantCounter;-). Of course! It must have been late when I named this class... I think I'll go change the name in my code right now. -- http://mail.python.org/mailman/listinfo/python-list

Re: generators shared among threads

2006-03-07 Thread Alex Martelli
<[EMAIL PROTECTED]> wrote: > Thanks for the great advice, Alex. Here is a subclass that seems to > work: You're welcome! > from Queue import Queue > from itertools import count > > class reentrantQueue(Queue): > def _init(self, maxsize): > self.maxsize = 0 > self.queue = []

Re: generators shared among threads

2006-03-06 Thread jess . austin
Thanks for the great advice, Alex. Here is a subclass that seems to work: from Queue import Queue from itertools import count class reentrantQueue(Queue): def _init(self, maxsize): self.maxsize = 0 self.queue = [] # so we don't have to override put() self.counter =

Re: generators shared among threads

2006-03-05 Thread Alan Kennedy
[EMAIL PROTECTED] > def f() > i = 0 > while True: > yield i > i += 1 > g=f() > > If I pass g around to various threads and I want them to always be > yielded a unique value, will I have a race condition? Yes. Generators can be shared between threads, but they cannot be res

Re: generators shared among threads

2006-03-04 Thread Alex Martelli
<[EMAIL PROTECTED]> wrote: > hi, > > This seems like a difficult question to answer through testing, so I'm > hoping that someone will just know... Suppose I have the following > generator, g: > > def f() > i = 0 > while True: > yield i > i += 1 > g=f() > > If I pass g

generators shared among threads

2006-03-04 Thread jess . austin
hi, This seems like a difficult question to answer through testing, so I'm hoping that someone will just know... Suppose I have the following generator, g: def f() i = 0 while True: yield i i += 1 g=f() If I pass g around to various threads and I want them to always be y