获取Python中忙碌CPU的数量
我正在写一个 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
的大小保持不变。