我正在阅读这个问题,询问生成器是否是线程安全的,一个答案说:
它不是线程安全的;同时调用可能交错,并与局部变量混淆。
另一个答案表明,您可以使用锁来确保一次只有一个线程使用生成器。
我是多线程新手。谁能设计出一个例子来说明当您使用无锁发生器时发生了什么?
例如,如果我这样做,似乎没有任何问题:
import threading
def generator():
for i in data:
yield i
class CountThread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
for i in gen():
print '{0} {1}'.format(self.name, i)
data = [i for i in xrange(100)]
gen = generator()
a = CountThread('a')
b = CountThread('b')
a.start()
b.start()
运行此示例。
您将看到10,000个数字将在线程之间“共享”。您不会在两个线程中看到10000个数字。
实际上,一个线程最有可能看到所有数字。
import threading
class CountThread(threading.Thread):
def __init__(self, gen):
threading.Thread.__init__(self)
self.gen = gen
self.numbers_seen = 0
def run(self):
for i in self.gen:
self.numbers_seen += 1
def generator(data):
for _ in data:
yield data
gen = generator(xrange(10000))
a = CountThread(gen)
b = CountThread(gen)
a.start()
b.start()
a.join()
b.join()
print "Numbers seen in a", a.numbers_seen
print "Numbers seen in b", b.numbers_seen
实际上,如果发生Python在执行期间切换线程的情况(只是使用一个大于10000的值,例如10000000),则会得到一个异常:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 808, in __bootstrap_inner
self.run()
File "test.py", line 10, in run
for i in self.gen:
ValueError: generator already executing
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句