我在 python 中使用 itertools.permutations 函数生成了排列。问题是结果非常大,我想用多个线程来完成它,但真的不知道如何完成它,这是我到目前为止所拥有的:
perms = itertools.permutations('1234', r=4)
#I would like to iterate through 'perms' with multiple threads
for perm in perms:
print perm
我在 python 中使用 itertools.permutations 函数生成了排列。问题是结果非常大,我想用多个线程来完成它,但真的不知道如何完成它,这是我到目前为止所拥有的:
perms = itertools.permutations('1234', r=4)
#I would like to iterate through 'perms' with multiple threads
for perm in perms:
print perm
如果您要对来自排列生成器的项目执行的工作是 CPU 密集型的,那么您可能希望使用进程而不是线程。CPython 的全局解释器锁 (GIL) 在执行 CPU 密集型工作时使多线程的价值有限。
相反,使用multiprocessing
模块的Pool
类,如下所示:
import multiprocessing
import itertools
def do_stuff(perm):
# whatever
return list(reversed(perm))
if __name__ == "__main__":
with multiprocessing.Pool() as pool: # default is optimal number of processes
results = pool.map(do_stuff, itertools.permutations('1234', r=4))
# do stuff with results
请注意,如果您将进行迭代results
(而不是将其作为列表进行操作),您可以使用imap
而不是map
获取一个迭代器,您可以使用该迭代器来处理从工作进程产生的结果。如果返回项目的顺序无关紧要,您可以使用imap_unordered
(我认为)节省一些内存。
Windows上if __name__ is "__main__"
需要样板文件,其中multiprocessing
模块必须解决操作系统的限制(否fork
)。
假设你的处理函数是你想要做的 f(x)
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes
perms = itertools.permutations('1234', r=4)
for r in pool.map(f, perms):
print (r)
事实上,使用线程不会并行执行进程,除非它是 IO 绑定的。如果它受 CPU 限制并且你有一个四核,那么这就是要走的路。如果您没有多核并且它受 CPU 限制,那么恐怕使其并行不会改善您目前的情况。
在线程之间拆分perms 数的索引,然后使用此函数从每个线程中的索引生成 perm,而不是生成所有 perms 并在线程之间拆分它们。
Python 的futures模块可以很容易地在线程之间拆分工作。在此示例中,将使用 4 个线程,但您可以根据需要对其进行修改。
from concurrent import futures
def thread_process(perm):
#do something
with futures.ThreadPoolExecutor(max_workers=4) as executor:
for perm in perms:
executor.submit(thread_process, perm)