6

我在 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
4

4 回答 4

4

如果您要对来自排列生成器的项目执行的工作是 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)。

于 2012-12-30T16:26:59.427 回答
1

假设你的处理函数是你想要做的 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 限制,那么恐怕使其并行不会改善您目前的情况。

于 2012-12-30T16:23:28.370 回答
1

在线程之间拆分perms 数的索引,然后使用此函数从每个线程中的索引生成 perm,而不是生成所有 perms 并在线程之间拆分它们。

于 2013-01-01T18:24:08.043 回答
0

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)
于 2012-12-30T16:22:47.557 回答