如何从python中的多个线程收集数据?

时间:2011-04-13 19:30:12

标签: python multithreading

我想在Python中使用多个线程来计算图像的像素值,最后要构建它,尽管我很难弄清楚如何获取线程的结果并收集它。这是设置:

创建了一个Queue.Queue()对象,以及一个threading.Thread()类子:

q = Queue.Queue()
class myThread(threading.Thread):
  def __init__(self, queue):
    self.queue = queue
    threading.Thread.__init__(self)
  def run(self):
    while True: # loop forever
      task = self.queue.get()
      rs = self.do_work(task) # I've got the result; now what to do with it?
      self.queue.task_done()

我的想法是收集500x500图像的像素数据,这个图像最初是250,000(500x500)个元素的列表,最终将用PIL制作成图像:

pixels = array.array('B', pixels).tostring()
im = Image.fromstring('L', size, pixels)
im.show()

所以我用每个像素的任务填充队列,并产生一个线程池:

for i in range(5):
  t = myThread(q)
  t.setDaemon(True)
  t.start()
for y in range(500):
  for x in range(500):
    q.put({'x':x, 'y':y})
q.join()

那么如何获取所有数据呢?我认为将250,000个元素列表传递给每个线程都是一个坏主意,两者都是为了传递的数据数组的大小,并且因为每个线程都会丢失来自其他线程的数据。

修改 对于那些想知道以多线程方式完成这项工作是否值得的人来说,计算图像坐标所做的工作是几个perlin噪声函数。它正在生成一个perlin 2D噪声点阵列(一个5x5网格),加上几个八度音程(10x10,20x20和40x40网格),并计算这些点之间的像素值。因此,对于最终图像中的每个像素,它必须每个八度音程执行三次数学运算(给定点周围的平均X点,给定点周围的平均Y点,并平均这些平均值),然后在八度音结果之间进行加权平均。

在我的8核Mac上,我看到Python进程在运行时使用1个线程和100%的处理器。虽然我知道我有8个内核并且已经看到进程显示400-600%的处理器使用以显示它们正在利用其他内核,我只是希望这个Python脚本可以做同样的事情。

3 个答案:

答案 0 :(得分:2)

Python有一个用于修改python级数据结构的全局锁,称为GIL。这使得很难有效地完成你想用线程做的事情。

但是,绝望不是!那种开发人员给了我们多处理模块。用多处理替换线程(使用multiprocessing.Process和multiprocessing.Queue代替),瞧,你的应用程序是一个多进程应用程序。

至于你的问题,你想要另一个队列,朝另一个方向走。

答案 1 :(得分:1)

我认为你应该使用两个队列。

一个用于工作/任务,一个用于输出。

任务完成后,将结果放在输出队列中。

答案 2 :(得分:0)

我会有一个可以被每个线程访问的全局列表。我实际上有这样的情况并且没有问题就这样做了。