【发布时间】:2016-12-15 19:41:25
【问题描述】:
我到处搜索,但没有找到任何使用多线程迭代循环的简单示例。
例如,我怎样才能多线程这个循环?
for item in range(0, 1000):
print(item)
有没有办法把它切成4个线程,所以每个线程有250次迭代?
【问题讨论】:
标签: python multithreading iteration
我到处搜索,但没有找到任何使用多线程迭代循环的简单示例。
例如,我怎样才能多线程这个循环?
for item in range(0, 1000):
print(item)
有没有办法把它切成4个线程,所以每个线程有250次迭代?
【问题讨论】:
标签: python multithreading iteration
从 Python 3.2 开始,concurrent.futures standard library 为 concurrently map a function across iterables 提供原语。由于map 和for 密切相关,因此可以轻松地将for 循环转换为多线程/多处理循环:
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
executor.map(print, range(0, 1000))
【讨论】:
最简单的方法是使用multiprocessing.dummy(使用线程而不是进程)和Pool
import multiprocessing.dummy as mp
def do_print(s):
print s
if __name__=="__main__":
p=mp.Pool(4)
p.map(do_print,range(0,10)) # range(0,1000) if you want to replicate your example
p.close()
p.join()
如果您想更好地利用多个 CPU,也许您也想尝试真正的多处理,但有一些警告和guidelines 需要遵循。
Pool 的其他方法可能更适合您的需求 - 取决于您实际尝试做什么。
【讨论】:
do_print 函数怎么办?
range(0, 1000)(Python 3.5)...
zip(在 Py2 上,replace bad zip with good zip using from future_builtins import zip)或 generator expression,因此参数是惰性生成的(根据需要) 而不是急切地(延迟第一次调用的调度并浪费内存)。
multiprocessing.dummy,那应该是不可能的;给出的Pool 构造函数只使用了四个工作线程。
您必须手动进行拆分:
import threading
def ThFun(start, stop):
for item in range(start, stop):
print item
for n in range(0, 1000, 100):
stop = n + 100 if n + 100 <= 1000 else 1000
threading.Thread(target = ThFun, args = (n, stop)).start()
此代码使用多线程,这意味着所有内容都将在单个 Python 进程中运行(即只会启动一个 Python 解释器)。
多处理,在另一个答案中讨论,意味着在几个 Python 解释器中运行一些代码(在几个 进程,而不是 线程)。这可能会利用所有可用的 CPU 内核,因此当您专注于代码的速度时(打印大量数字直到终端讨厌您!),这很有用,而不仅仅是并行处理。 1
1. multiprocessing.dummy 原来是 a wrapper around the threading module。 multiprocessing 和 multiprocessing.dummy 具有相同的接口,但第一个模块使用 processes 进行并行处理,而后者 - 使用 threads。
【讨论】:
multiprocessing.dummy 确实是 threading 模块的包装器,但 multiprocessing 本身的工作原理与答案的划掉部分中的描述完全相同。选择哪一个取决于一个人想要什么行为,代码是一样的(这是一件好事)。
multiprocessing 和 multiprocessing.dummy 具有相似的接口,但是模块的选择会影响行为(线程与进程)。
multiprocessing 和 multiprocessing.dummy拥有完全相同的界面,这就是重点。
multiprocessing.dummy 不小心省略了cpu_count 函数。