Linux 系统并未提供直接获取CPU 利用率的接口,一些应用程序通过访问/proc 文件系统中系统的状态统计从而计算得到CPU利用率。常用查看进程及其相关信息的top 命令和htop 命令即属于这一类。
本文简单介绍如何利用/proc/stat 文件计算CPU 利用率,这种经典方法在top 和htop 工具中也被采用,在StackOverflow 也有说明;接着,将上面经典方法获取的CPU 利用率和一种极端情况下的单核单任务的CPU占用率进行比较,单核单任务指的是,在隔离的单独CPU 和核心上只运行该程序(如果你对这有疑问,可以参考下core affinity 、core isolation 和non irqbalance)。
看下图htop 工具的截图:该系统有8个CPU核心,每个核心的CPU利用率位于图上方横向柱状图。8个核心中1-7都是被隔离的,1/3/4/5/6/7每个核心都分配了一个名称为grt_simple_conc_ispc 的线程,每个线程CPU 占用率(CPU%)位于图下方第5 列,可以看出CPU利用率(上方)和每个程序占CPU利用率(下方)结果是有差异的。
方法一
一种最直接计算程序占用CPU 使用率的计算方法是,采样N 次,如果有R 次该程序正在执行,则其占用CPU使用率为 R/N × 100%。
Linux 在/proc/{pid}/stat 文件中记录进程ID 为pid 的进程统计信息(按照类别分为几十个字段,详见 https://man7.org/linux/man-pages/man5/proc.5.html )。如果进程状态字符是R ,则表示进程正在运行(Running),如果状态字符是S ,则表示进程正在睡眠(Sleeping)。
将该方法作为CPU 利用率的前提是:该CPU 核心只运行该进程,尽量少地被中断。
计算CPU 利用率经典方法(方法二)
工具(如top 和htop)定时采样读取/proc/stat 文件内容,该文件记录了每个CPU核心所处不同状态的累计时间,再通过以下公式可计算得到指定核心CPU利用率:
previdle = previdle + previowait idle = idle + iowait prevnoidle = prevuser + prevnice + prevsystem + previrq + prevsoftirq + prevsteal noidle = user + nice + system + irq + softirq + steal prevtotal = previdle + prevnonidle total = idle + nonidle total_delta = total - prevtotal idle_delta = idle - previdle CPU_usage = (total_delta - idle_delta)/total_delta
以prev开头的变量是上一次采用数据,否则是当前采样数据,通过计算两次采样之间的CPU空闲时间(idle_delta)和总计时间(total_delta)得到CPU利用率,这是procs/top 工具默认使用的方法,也是最常见CPU利用率统计方法。
方法三
方法和约束情况类似于方法一,周期性读取/proc/{pid}/stat文件,获取进程用户态时间utime 和核态时间stime,按照如下公式计算CPU利用率
CPU_usage = (utime+stime)/sample_interval
其中,utime和stime代表进程用户态时间和核态时间,sample_interval是采样间隔。
下面是负载由轻到高,三种方法得到的CPU 利用率: