我已经看到了几种不同的方法来实现多处理(即通过循环遍历你想要的许多进程并创建一个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,)
不要理解这种语法,但它可以正常工作。
提前致谢!
答案 0 :(得分:0)
您在上面显示的方法的缺点是,您最终得到N
个进程,其中N
为len(sublists)
。如果说sublists
,100个元素长,那么最终会有100个并发运行的进程。这给系统内存带来了巨大负担,除非您的计算机上有超过100个内核,否则您只会损害性能,因为您不能同时执行超过cpu_count()
CPU绑定的进程。这意味着操作系统需要在进程之间不断进行上下文切换,以便尝试获取所有CPU时间,从而减慢速度。
使用multiprocessing.Pool()
创建固定数量的进程来执行工作(默认情况下为multiprocessing.cpu_count()
,这意味着您不会以大量进程结束。这样可以节省内存,并且减少因运行更多任务而导致的过多上下文切换,而不是使用内核来处理它们。
args=(entry,)
中的尾随逗号是必需的,因为args
关键字参数需要可迭代(如元组或列表)。在Python中,元组是用逗号创建的,而不是括号,所以只做args=(entry)
实际上等同于args=entry
。 entry
不一定是可迭代的,因此Process
会用它做错事。添加尾随逗号会创建一个元素元组,并使Process
满意。如果您有两个要传递的参数,则看起来更自然:args=(entry1, entry2)
。