Skip to content

Instantly share code, notes, and snippets.

@anandology
Created May 24, 2012 07:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anandology/2780044 to your computer and use it in GitHub Desktop.
Save anandology/2780044 to your computer and use it in GitHub Desktop.
Code to demonstrate issues of using iterators and generators in multi-threaded applications
import threading
def count():
i = 0
while True:
i += 1
yield i
class Counter:
def __init__(self):
self.i = 0
def __iter__(self):
return self
def next(self):
self.i += 1
return self.i
def loop(func, n):
for i in range(n):
func()
def run(counter, repeats=1000, nthreads=10):
threads = [threading.Thread(target=loop, args=(counter.next, repeats)) for i in range(nthreads)]
for t in threads:
t.start()
for t in threads:
t.join()
def main():
c1 = count()
c2 = Counter()
run(c1, repeats=100000, nthreads=2)
print "c1", c1.next()
run(c2, repeats=100000, nthreads=2)
print "c2", c2.next()
if __name__ == "__main__":
main()
Exception in thread Thread-2:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 477, in run
self.__target(*self.__args, **self.__kwargs)
File "count.py", line 22, in loop
func()
ValueError: generator already executing
c1 112106
c2 158368
class Counter:
def __init__(self):
self.i = 0
self.lock = threading.Lock()
def __iter__(self):
return self
def next(self):
with self.lock:
self.i += 1
return self.i
class threadsafe_iter:
def __init__(self, it):
self.it = it
self.lock = threading.Lock()
def __iter__(self):
return self
def next(self):
with self.lock:
return self.it.next()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment