获取Python中忙碌CPU的数量

7 投票
3 回答
3029 浏览
提问于 2025-04-18 13:13

我正在写一个 multiprocessing 的程序,打算在一台有很多CPU的服务器上运行。不过,这台服务器有很多用户,使用情况可能会有所不同。所以我想根据当前的负载来调整使用的处理器数量。

  • 有没有办法在Python中估算当前有多少个CPU正在忙碌?我只找到 multiprocessing.cpu_count() 这个方法。
  • 附加问题:在活动进行中,是否可以根据服务器的负载变化来更改 multiprocessing.Pool(processes=no_cpus) 的处理器数量?

3 个回答

1

我觉得你问题的最佳解决方案是psutil这个库,它可以帮助你在不同的操作系统中管理一些CPU和内存的使用情况:

psutil是一个模块,它提供了一种接口,可以用Python来获取正在运行的进程和系统使用情况(比如CPU和内存)的信息。它的工作方式很方便,类似于一些工具,比如ps、top和Windows任务管理器。

目前,它支持Linux、OS X、FreeBSD和Windows,兼容的Python版本从2.4到3.1,使用的是同一套代码。

4

我按照johntellsall的解决方案做了,这里有一个简单的示意图。因为在我看来,Python把虚拟CPU和实际CPU搞混了。所以我决定根据过去15分钟的平均负载来进行校准。

这里的睡眠时间是随便定的。

def sleepForMultiCore():
    # divide by 2 since Python does not distinguish physical and virtual core
    cores = 0.5*mp.cpu_count()
    loadAvg = os.getloadavg()[2]

    if loadAvg > cores*1.3:
        sleepTime = 5*60
    elif loadAvg > cores:
        sleepTime = 2*60
    elif loadAvg > cores*0.9:
        sleepTime = 1*60
    else:
        sleepTime = 0
    print ('sleeping for ', sleepTime)
    time.sleep(sleepTime)
7

这里面有一些复杂的地方...

  • 你无法确定哪些CPU正在忙碌

在Linux系统中,进程(和线程)是由内核在任何CPU上调度的。甚至要确定“当前的CPU”也很麻烦——可以看看这个链接:我怎么能知道一个线程在哪个CPU核心上运行?

  • multiprocessing.Pool是用来启动N个工作进程的,这些进程会“永远”运行。每个进程会从一个任务队列中接受任务,完成工作后再输出数据。一个Pool的大小是不会改变的。

这里有两个建议:

  • uptime命令的输出大概是这样的:

19:05:07 up 4 days, 20:43, 3 users, load average:0.99, 1.01, 0.82

最后三个数字是过去一分钟、五分钟和十五分钟的“负载平均值”。可以考虑用第一个数字来平衡你应用的负载。

  • 考虑让你的应用在完成每个工作后执行time.sleep(factor)

这样,当系统忙碌(负载高)时,你可以增加这个因子,而当系统比较闲(负载低,比如在上网)时,可以缩短这个延迟。Pool的大小保持不变。

撰写回答