实现多处理的最佳方式?

时间:2014-08-11 15:24:37

标签: python multiprocessing

我已经看到了几种不同的方法来实现多处理(即通过循环遍历你想要的许多进程并创建一个Process(),或者使用multiprocessing.Pool())我只是想知道它们之间有什么区别方法,并且会比另一方更好/更有效吗?

我当前的项目涉及将主机名列表拆分为n个子列表,然后在每个子列表上执行一些命令(每个子列表都在其自己的进程中) - 最快的方法是什么?截至目前,最简单的似乎是:

def worker(hostList):
    for entry in hostList:
        # DoStuff

def main():
    jobs = []
    for entry in sublists:
        p = multiprocessing.Process(target=worker, args=(entry,))
        jobs.append(p)
        p.start()

使用此方法而不是Pool()

是否有任何缺点

另外 - 只是旁注:为什么逗号在

args=(entry,)

不要理解这种语法,但它可以正常工作。

提前致谢!

1 个答案:

答案 0 :(得分:0)

您在上面显示的方法的缺点是,您最终得到N个进程,其中Nlen(sublists)。如果说sublists,100个元素长,那么最终会有100个并发运行的进程。这给系统内存带来了巨大负担,除非您的计算机上有超过100个内核,否则您只会损害性能,因为您不能同时执行超过cpu_count() CPU绑定的进程。这意味着操作系统需要在进程之间不断进行上下文切换,以便尝试获取所有CPU时间,从而减慢速度。

使用multiprocessing.Pool()创建固定数量的进程来执行工作(默认情况下为multiprocessing.cpu_count(),这意味着您不会以大量进程结束。这样可以节省内存,并且减少因运行更多任务而导致的过多上下文切换,而不是使用内核来处理它们。

args=(entry,)中的尾随逗号是必需的,因为args关键字参数需要可迭代(如元组或列表)。在Python中,元组是用逗号创建的,而不是括号,所以只做args=(entry)实际上等同于args=entryentry不一定是可迭代的,因此Process会用它做错事。添加尾随逗号会创建一个元素元组,并使Process满意。如果您有两个要传递的参数,则看起来更自然:args=(entry1, entry2)