实施多进程的最佳方式是什么?

0 投票
1 回答
1031 浏览
提问于 2025-04-18 16:51

我看到有几种不同的方法来实现多进程,比如可以通过循环创建你想要的进程数量,或者使用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

你上面提到的方法有个缺点,就是会产生 N 个进程,其中 Nlen(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)

撰写回答