在多个cpu环境中并行化大量功能

时间:2014-10-31 14:40:49

标签: python python-2.7 parallel-processing multiprocessing

我想创建一个函数,在给定函数列表和相对参数的情况下,启动尽可能多的进程以并行化这些任务。运行进程的数量不能超过我的CPU核心数。当一个过程结束时,应该用另一个过程替换它,直到结束。

我尝试使用python Pools实现这样的功能。这是我的功能:

from multiprocessing import Pool, cpu_count

CPUS = cpu_count()

def parallelize(functions, args):
    results = []
    if CPUS > 1:
        for i in xrange(0, len(functions), CPUS):
            pool = Pool()
            for j in xrange(CPUS):
                if i + j >= len(functions):
                    break
                results.append(pool.apply_async(functions[i + j], args = args[i + j]))
            pool.close()
            pool.join()
        map(lambda x: x.get(), results)
    else:
        for i in xrange(len(functions)):
            results.append(functions[i](*args[i]))
    return results

此实现细分了批量中的函数列表。每个批量维度等于实际CPU的数量。问题是它实际上等待每个函数完成,然后再次启动另一大部分进程 我不想要这种行为,因为如果批量中的函数非常慢,那么另一个cpus会在开始新进程之前等待它完成。

什么是正确的方法?

1 个答案:

答案 0 :(得分:2)

您似乎过度复杂了。无论您为其提供多少工作项,multiprocessing.Pool将始终以您告诉它的流程数运行。因此,如果您创建Pool(CPUS)Pool将永远不会同时运行超过CPUS个任务,即使您提供了CPUS * 100个任务。所以它满足了你的要求,即在没有你做任何特殊工作的情况下,永远不要运行比拥有CPU更多的任务。因此,您可以遍历整个方法和参数列表,并在其上调用apply_async,而不必担心批量调用。 Pool将执行所有任务,但一次只执行CPUS个任务:

def parallelize(methods, args):
    results = []
    if CPUS > 1:
        pool = Pool(CPUS)
        for method, arg in zip(methods, args):
            results.append(pool.apply_async(method, args=arg))
        pool.close()
        pool.join()
        out = map(lambda x: x.get(), results)
    else:
        for i in xrange(len(methods)):
            results.append(methods[i](*args[i]))
    return results