linux/proc/stat计算cpu使用率

Posted sysu_lluozh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux/proc/stat计算cpu使用率相关的知识,希望对你有一定的参考价值。

/proc/stat中包含系统启动以来的很多系统和内核的统计信息,比如包括CPU运行情况、中断情况、启动时间、上线文切换次数、运行中的进程等信息都在其中

一、信息内容

# Linux下查看/proc/stat的具体信息如下
[root@WSC-31-2 ~]# cat /proc/stat 
cpu  60382 1 80032 198934063 2349 0 109 0 0 0
cpu0 2405 0 2084 4140924 682 0 6 0 0 0
...  # 此处较多冗余信息,简化之
cpu47 200 0 134 4147222 10 0 0 0 0 0

intr 33622492 64 ... 0 0 0 0 # 此处较多冗余信息,简化之
ctxt 68533835
btime 1528905555
processes 318904
procs_running 1
procs_blocked 0
softirq 16567860 0 3850777 8555 5448802 116727 0 1 3577293 1290 3564415

这些数字指明了CPU执行不同的任务所消耗的时间(从系统启动开始累计到当前时刻)
时间单位是USER_HZ或jiffies(一般地等于10ms)

二、字段解读

2.1 CPU信息

内容的第一行是CPU的整体信息,紧跟着是各个CPU核的信息,各个字段内容如下:

name   user  nice   system      idle      iowait  irrq  softirq  steal guest guest_nice 
cpu    60382   1     80032     198934063   2349     0     109      0     0       0
cpu0   2405    0     2084      4140924     682      0     6        0     0       0
...  # 此处较多冗余信息,简化之
cpu47  200     0     134       4147222     10       0     0        0     0       0

各个字段如下:

cpu指标含义时间单位备注
user用户态时间jiffies一般/高优先级,仅统计nice<=0
nicenice用户态时间jiffies低优先级,仅统计nice>0
system内核态时间jiffies
idle空闲时间jiffies不包含IO等待时间
iowaitI/O等待时间 jifjiffies硬盘IO等待时间
irq硬中断时间jiffies
softirq软中断时间jiffies
steal被盗时间jiffies虚拟化环境中运行其他操作系统上花费的时间
guest来宾时间jiffies操作系统运行虚拟CPU花费的时间
guest_nicenice来宾时间jiffies运行一个带nice值的guest花费的时间

2.2 中断信息

intr 33622492 64 ... 0 0 0 0

这行给出中断的信息,第一个为自系统启动以来,发生的所有中断的次数
之后的每个数对应一个特定的中断自系统启动以来所发生的次数

2.3 上下文切换信息

ctxt 68533835

自系统启动以来CPU发生的上下文交换的次数

2.4 运行时间

btime 1528905555

表示系统自启动以来已经运行了的时间,单位为秒(s)

2.5 所有任务信息

processes 318904

表示自系统启动以来所创建的任务的数量

2.6 运行任务信息

procs_running 1

表示当前运行队列中正在运行着的任务数量

2.7 阻塞任务信息

procs_blocked 0

表示当前被阻塞的任务的数量

2.8 软中断信息

softirq 16567860 0 3850777 8555 5448802 116727 0 1 3577293 1290 3564415

表示从系统启动以来的软中断计数,第一列表示所有软中断的总和
之后各列表示某个指定软中断的数量

总体注解如下:

# Linux下查看/proc/stat的具体信息如下
[root@WSC-31-2 ~]# cat /proc/stat 
cpu  60382 1 80032 198934063 2349 0 109 0 0 0
cpu0 2405 0 2084 4140924 682 0 6 0 0 0
...  # 此处较多冗余信息,简化之
cpu47 200 0 134 4147222 10 0 0 0 0 0

intr 33622492 64 ... 0 0 0 0
#这行给出中断的信息,第一个为自系统启动以来,发生的所有中断的次数
#之后的每个数对应一个特定的中断自系统启动以来所发生的次数  

ctxt 68533835                   #自系统启动以来CPU发生的上下文交换的次数

btime 1528905555				#表示系统自启动以来已经运行了的时间,单位为秒(s)

processes 318904				#表示自系统启动以来所创建的任务的数量

procs_running 1					#当前运行队列中正在运行着的任务数量

procs_blocked 0					#当前被阻塞的任务的数量

softirq 16567860 0 3850777 8555 5448802 116727 0 1 3577293 1290 3564415
#表示从系统启动以来的软中断计数,第一列表示所有软中断的总和
#之后各列表示某个指定软中断的数量

三、说明

  1. 1 jiffies = 0.01s = 10ms
  2. 常用计算等式:CPU时间 = user + system + nice + idle + iowait + irq + softirq
  3. man手册iowait有单独说明,iowait时间是不可靠值,具体原因如下:
    1)CPU不会等待I/O执行完成,而iowait是等待I/O完成的时间。当CPU进入idle状态,很可能会调度另一个task执行,所以iowait计算时间偏小
    2)多核CPU中,iowait的计算并非某一个核,因此计算每一个cpu的iowait非常困难
    3)这个值在某些情况下会减少

四、源码

根据上面的/proc/stat字段信息,使用Java计算出cpu的使用率

private static final int SLEEP_TIME = 100;

/**
* 获取cpu的使用率
*/
public static float getCpuInfo() throws IOException, InterruptedException {
        File file = new File("/proc/stat");
        //第一次采集CPU时间
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        StringTokenizer token = new StringTokenizer(br.readLine());
        token.nextToken();
        long user1 = Long.parseLong(token.nextToken() + "");
        long nice1 = Long.parseLong(token.nextToken() + "");
        long sys1 = Long.parseLong(token.nextToken() + "");
        long idle1 = Long.parseLong(token.nextToken() + "");
        //间隔一段睡眠时间
        Thread.sleep(SLEEP_TIME);
        //第一次采集CPU时间
        br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        token = new StringTokenizer(br.readLine());
        token.nextToken();
        long user2 = Long.parseLong(token.nextToken());
        long nice2 = Long.parseLong(token.nextToken());
        long sys2 = Long.parseLong(token.nextToken());
        long idle2 = Long.parseLong(token.nextToken());
        //通过两次的差值计算出cpu使用率
        float cpuInfo = (float)((user2 + sys2 + nice2) - (user1 + sys1 + nice1)) * 100.0F / (float)((user2 + nice2 + sys2 + idle2) - (user1 + nice1 + sys1 + idle1));
        return (float)Math.round(cpuInfo*100)/100;
    }

以上是关于linux/proc/stat计算cpu使用率的主要内容,如果未能解决你的问题,请参考以下文章

linux /proc/stat 文件说明

linux /proc/stat

写代码如何合理使用和优化我们的机器资源(CPU内存网络磁盘)

linux系统下CPU利用率的计算

linux系统下CPU利用率的计算

c#计算特定应用程序的CPU使用率