python线程 - 迭代n个任务时总是有x个活动线程

时间:2014-09-16 17:51:38

标签: python multithreading list queue

我基本上想做的是:

import threading
import Queue

def test_thread(elem, q):
    q.put(elem ** 2)

a = [1,2,3,4,5,6,7,8]
q = Queue.Queue()
results = []
for x in range(8):
    print x
    threading.Thread(target=test_thread, args=(a[x], q)).start()
    results.append(q.get())

但是我没有立即运行所有线程,而是想在列表中仅运行2并且迭代。一旦完成一个线程,就应该处理列表中的下一个值。我找不到一个例子,我不知道如何为此构建循环。

另外,我不了解Queue的行为。我原以为所有平方数都在队列中。但相反,只有一个价值? (上面的代码已更改为将所有结果存储在“结果”中)。提示,评论,关键词非常受欢迎。

编辑:

第二个问题:

抱歉,我认为q.get()会返回所有结果。但它只是像时尚一样将元素放在队列中。

1 个答案:

答案 0 :(得分:2)

您可以使用线程池:

import threading
from multiprocessing.pool import ThreadPool

def test_thread(elem):
    return elem ** 2

a = [1,2,3,4,5,6,7,8]
pool = ThreadPool(2) # 2 worker threads
results = []
for x in range(8):
    print x
    results.append(pool.apply_async(test_thread, args=(a[x],)))

results = [result.get() for result in results]
# You can also replace this for loop altogether using pool.map
# and get the same result:
# results = pool.map(test_thread, range(8))
print(results)

输出:

0
1
2
3
4
5
6
7
[1, 4, 9, 16, 25, 36, 49, 64]

ThreadPool类是multiprocessing模块中大部分未记录的部分。它也可以通过multiprocessing.dummy.Pool访问。它允许您创建一个线程池来处理任意数量的工作项,同时始终将同时处理的工作项数量限制为您指定的内容。您可以使用普通multiprocessing.Pool的文档来了解其API。它完全相同,除了它所说的" process",你用" thread"替换它。

我不确定我是否会关注Queue.Queue问题的第二部分。在for循环的每次迭代中,您将一个项目放入Queue内的test_thread,然后使用results.append(q.get())在for循环中使用它。因此,虽然Queue中一次只有一个项目,但它用于传输results列表中最终的所有值 - {{1}中的每个项目列表。