Python:为什么不同的线程从一个生成器获取自己的一系列值? [英] Python: Why different threads get their own series of values from one generator?

查看:92
本文介绍了Python:为什么不同的线程从一个生成器获取自己的一系列值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Python中的多线程.我想知道如何使用生成器将数据提供给多个线程.这是我写的:

I'm learning multithreading in Python. I want to know how to provide data to multiple threads using generators. Here's what I wrote:

  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()

我认为该列表只会重复一次.但是似乎每个线程都独立地遍历列表.

I thought the list would only be iterated for once. But it seems that each thread is interating through the list independently.

输出:

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)

此的根本原因是什么?我该如何重写程序,以便列表中的值仅打印一次.

What is the underlying reason for this? How can I rewrite the program so that the values in the list will only be printed once.

推荐答案

您可以在run函数的每个线程中实例化一个新的生成器:

You instantiate a new generator in each thread in run function with this:

for i in generator():

每个generator调用都会返回一个生成器的新实例:

each generator call returns a new instance of generator:

>>> data = [i for i in xrange(10)]
>>> a, b = generator(), generator()
>>> id(a), id(b)
(37528032, 37527952)

此处ab具有不同的ID,即使没有线程也会产生相同的结果:

Here a and b have different ids, and generate identical results even without threading:

>>> list(a), list(b)
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

但是请注意,生成器不是线程安全的,在线程应用程序中使用它们很棘手.您必须担心锁定,请参见示例,否则有时会出现ValueError: generator already executing错误.或者,您可以使用 Queue.Queue 进行线程通信

Note however, that generators aren't thread safe, it is tricky to use them in threaded application. You have to worry about locking, see example, or you'll get ValueError: generator already executing error once in a while. Alternatively you can use Queue.Queue for thread communication.

这篇关于Python:为什么不同的线程从一个生成器获取自己的一系列值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆