Created
May 24, 2012 07:36
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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