Hai*_*ang 3 python multithreading generator
我正在学习Python中的多线程.我想知道如何使用生成器向多个线程提供数据.这是我写的:
import threading
data = [i for i in xrange(100)]
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 generator():
print '{0} {1}'.format(self.name, i)
a = CountThread('a')
b = CountThread('b')
a.start()
b.start()
Run Code Online (Sandbox Code Playgroud)
我以为列表只会被迭代一次.但似乎每个线程都是独立地通过列表进行交互.
输出:
a 0
a 1
a 2
b 0
a 3
a 4
b 1
b 2
a 5
a 6
a 7
a 8
a 9
b 3
b 4
b 5
b 6
b 7
b 8
...
(200 lines)
Run Code Online (Sandbox Code Playgroud)
这是什么原因?如何重写程序,以便列表中的值只打印一次.
您可以在run函数中的每个线程中实例化一个新的生成器:
for i in generator():
Run Code Online (Sandbox Code Playgroud)
每次generator调用都会返回一个新的生成器实例:
>>> data = [i for i in xrange(10)]
>>> a, b = generator(), generator()
>>> id(a), id(b)
(37528032, 37527952)
Run Code Online (Sandbox Code Playgroud)
这里a并b具有不同的ID,甚至不用穿产生相同的结果:
>>> list(a), list(b)
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Run Code Online (Sandbox Code Playgroud)
但请注意,生成器不是线程安全的,在线程应用程序中使用它们很棘手.您必须担心锁定,请参阅示例,否则您ValueError: generator already executing偶尔会遇到错误.或者,您可以使用Queue.Queue进行线程通信.