使用multiprocessing.Pool分配并行作业的问题

时间:2017-09-18 18:08:35

标签: python python-2.7 parallel-processing multiprocessing

multiprocessing.Pool正在运行时出现问题。以下函数process_next应该由所有工作人员在每次迭代的同时执行(我的机器有8个逻辑核心,所以我有multiprocessing.cpu_count()= 8):

import multiprocessing

def process_next((X, y)):
    try:
        # Operation on X and y should be performed by ALL workers
        print multiprocessing.current_process().name
    except KeyboardInterrupt:
        return {}


p = multiprocessing.Pool(processes=multiprocessing.cpu_count())
_arguments = []
itr = 5
for _ in range(itr):
    print " >>>>> Iteration (%d) <<<<<" % _
    X = range(5)
    y = range(2)
    _arguments.append((X, y))
    p.map(process_next, _arguments)
    print 

p.close()
p.join()

输出如下:

 >>>>> Iteration (0) <<<<<
PoolWorker-1

 >>>>> Iteration (1) <<<<<
PoolWorker-2
PoolWorker-3

 >>>>> Iteration (2) <<<<<
PoolWorker-4
PoolWorker-5
PoolWorker-6

 >>>>> Iteration (3) <<<<<
PoolWorker-1
PoolWorker-7
PoolWorker-2
PoolWorker-8

 >>>>> Iteration (4) <<<<<
PoolWorker-3
PoolWorker-4
PoolWorker-5
PoolWorker-6
PoolWorker-1

我希望每次迭代都涉及所有工人。我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

multiprocessing模块定义:

  

multiprocessing.<Process>.name
name是一个字符串,仅用于识别目的。它没有语义。多个进程可以使用相同的名称。

.map()方法映射应该处理的内容:

.map( func, iterable [, chunksize] ) - 来自iterable的尽可能多的参数,但不是更多而池容量允许一次,当然,不小于iterable-parameter的长度。

它只支持一个iterable参数。它会阻塞,直到结果准备就绪。

所以没有理由期望在任何情况下都可以使.Process()的{​​{1}}个实例加载2个以上的元素iterable(不论{ {1}}预加载/加载比例辅助值)。

因此,在所有情况下,chunksize - 列表仍然较短(在_arguments要求查看之前使用 print( len( _arguments ) ) 进行测试),没有有理由映射比p.map()中列出的更多元组 - 列表而不是所有池的_arguments实例都被调用了。

在2.7 Process中也可以使用.Pool()实例化属性,其中maxtasksperchild是工作进程在退出之前可以完成的任务数,并替换为新的工作进程,以释放未使用的资源。 默认maxtasksperchildmaxtasksperchild,这意味着工作流程与池一样长。

我该怎么做?

在外部循环中追加一个接一个的元组,不能有效地利用None容量。更改.Pool(),以便将更多任务传递到.map() - 实例。

如果您更好地预构建.Pool()方法中使用的iterable.map() - 实例将更好地加载其成员,并可能使用其所有容量来处理所有.Pool() - 现在的元素。