如何制作Python';s多进程繁殖以使用所有可用的CPU

如何制作Python';s多进程繁殖以使用所有可用的CPU,python,amazon-ec2,multiprocessing,Python,Amazon Ec2,Multiprocessing,我有一个AWS实例,它有32个CPU: ubuntu@ip-122-00-18-114:~$ cat /proc/cpuinfo | grep processor | wc -l 32 我的问题是如何使用Python的 因此,每个命令都在每个CPU上运行 例如,在下面的代码中,每个命令会在每个可用的CPU上运行吗 import multiprocessing import os POOL_SIZE = 32 cmdlist = [] for param in items: cmd

我有一个AWS实例,它有32个CPU:

ubuntu@ip-122-00-18-114:~$ cat /proc/cpuinfo  | grep processor  | wc -l
32
我的问题是如何使用Python的 因此,每个命令都在每个CPU上运行

例如,在下面的代码中,每个命令会在每个可用的CPU上运行吗

import multiprocessing
import os
POOL_SIZE = 32
cmdlist = []
for param in items:
    cmd = """./cool_command %s""" % (param)
    cmdlist.append(cmd)
p = multiprocessing.Pool(POOL_SIZE)
p.map(os.system, cmdlist)
如果没有,正确的方法是什么


如果我设置池大小>处理器(CPU),会发生什么?

简单的问题是“不准确”。您可以使用
os.cpu\u count()
函数获取cpu计数,并运行此数量的进程。但只有操作系统将进程分配给CPU。更重要的是,它可能会在一段时间内切换到另一个cpu。我不会在这里解释它是如何工作的

如果您在该服务器上运行其他“繁重”的进程,例如数据库或web服务器,那么它们的执行可能也需要一些cpu时间


一些好消息是,有一个名为exists的东西可以满足您的需要。但这是对操作系统的一种微调。

首先,对你的措辞进行一点修正。CPU有不同的内核,每个内核都有超线程。每个超线程都是运行处理器的逻辑单元。在Amazon上,您有32个vCPU,它们对应于超线程,而不是CPU或内核。这对于这个问题并不重要,但如果你做进一步的研究,重要的是要有正确的措辞。下面我将把Hyperread的“最低逻辑处理单元”称为vCPU

如果未指定池大小:

p = multiprocessing.Pool()
p.map(os.system, cmdlist)
然后python将自己(通过
os.cpu\u count()
)找到可用的逻辑处理器(在您的例子中是32个VCPU)的数量

在正常情况下,所有32个进程都在单独的vCPU上运行,因为Linux试图平衡它们之间的负载。 但是,如果有其他繁重的进程同时运行,那么两个进程可能在同一个vCPU上运行

这里要理解的关键是Linux调度程序是如何工作的:它定期重新调度进程,以便所有处理单元的利用率大致相同。这意味着,如果您只启动16个进程,那么它们将分布到所有32个vCPU,并大致相同地使用它们(使用
htop
查看负载如何分布)


如果我设置池大小>处理器(CPU),会发生什么

如果启动的进程比可用的vCPU多,那么一些进程需要共享一个vCPU。这意味着调度程序在上下文切换中周期性地切换出进程。如果您的进程是CPU受限的(使用100%的CPU,例如,当您进行数字运算时),那么拥有比VCPU更多的进程将降低整个进程的速度,因为您将拥有降低速度的上下文开关,并且如果您在进程之间进行通信(不是在您的示例中,而是在进行多处理时通常会做的事情)这也会减慢速度


不过。如果您的进程不是CPU绑定的,而是磁盘绑定的(需要等待磁盘进行读/写)或网络绑定的(例如等待其他服务器应答),则调度程序会将它们关闭,以便为另一个进程腾出空间,因为它们无论如何都需要等待。

如果设置池大小>,可能会出现重复的情况(CPU)?@neversaint:我在回答中回答了你的补充问题,并在开头添加了一些关于措辞的词语