Python:为什么不同的线程从一个生成器获得自己的一系列值?

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)

这是什么原因?如何重写程序,以便列表中的值只打印一次.

alk*_*lko 9

您可以在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)

这里ab具有不同的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进行线程通信.