实施多进程的最佳方式是什么?
我看到有几种不同的方法来实现多进程,比如可以通过循环创建你想要的进程数量,或者使用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 个回答
你上面提到的方法有个缺点,就是会产生 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)
。