-
准备知识
-
/proc
文件系统是一个伪文件系统,该文件系统中存储着内核控制相关信息,通俗点说就是这个目录是虚拟的,它受内核直接控制,存储与内核控制相关的数据,与其他目录不同的是/proc
目录不是真实存储在硬盘中的,它的数据存储在内存中,但是由于它和其他目录一样把自己注册到虚拟文件系统层了,所以我们还是能看到这个目录相关信息,然而只有虚拟文件系统层调用它的时候,他才会建立相关文件和目录并与内核沟通获取相关信息。 -
上面我们说道
/proc
文件系统存储着内核控制相关信息的目录,该目录下的/proc/stat
文件存储的是CPU
相关信息,我们想要获取CPU
相关信息最直接和最快速的方式就是读取该文件,其实Linux下
很多的工具都是读取的这个文件。在这个文件中包含了所有的CPU
活动信息,并且该文件中所有值都是从系统启动算起直到访问文件的这一刻的数据。如下就是某一刻/proc/stat
文件中的数据:cpu 499312 1086 227835 10498412 3803 0 10904 0 0 0 cpu0 125361 278 56675 2626355 450 0 2242 0 0 0 cpu1 124704 288 57768 2627741 350 0 2168 0 0 0 cpu2 130284 261 55543 2620559 2442 0 1762 0 0 0 cpu3 118961 258 57848 2623755 560 0 4731 0 0 0 intr 46393945 9 924 0 0 0 0 0 0 1 14751 0 0 215 0 0 0 139800 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4476 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 408029 0 283839 7963609 40 945 1535489 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ctxt 124171702 btime 1539737966 processes 626819 procs_running 4 procs_blocked 0 softirq 27922585 9163685 6158929 26 485 278010 0 160301 6495615 0 5665534
数据单位:jiffies
-
如上数据中从cpu到cpu3五行(从左到右按顺序)每一列的含义如下:
user
:如上499312、125361、124704等,用户态时间。nice
:如上1086等第二列数据,nice
值为负数的进程所占时间。system
:如上第三列数据,核心时间。idle
:如上第四列数据,除硬盘IO等待时间之外的时间。iowait
:如上第五列数据,硬盘IO等待时间。irq
:如上第六列数据,硬中断时间。softirq
如上第七列数据,软中断时间。
C P U t i m e = u s e r l i n e : 1 + n i c e l i n e : 2 + s y s t e m l i n e : 3 + i d l e l i n e : 4 + i o w a i t l i n e : 5 + i r q l i n e : 6 + s o r t i r q l i n e : 7 CPU_{time}=user_{line:1} +nice_{line:2} + system_{line:3} + idle_{line:4} + iowait_{line:5} + irq_{line:6} + sortirq_{line:7} CPUtime=userline:1+niceline:2+systemline:3+idleline:4+iowaitline:5+irqline:6+sortirqline:7
-
剩下的几行:
initr
:中断次数ctxt
:交换次数btime
:从系统启动到访问文件为止的时间。processes
:任务数。procs_runing
:当前运行队列的任务数。procs_blocked
:当前被阻塞的任务数。
-
CPU
利用率计算可以采用两点采样取差值的方式:C P U u s a g e = ( i d l e 第 二 次 采 样 − i d l e 第 一 次 采 样 ) / ( C P U t i m e 第 二 次 采 样 − C P U t i m e 第 一 次 采 样 ) ∗ 100 CPU_{usage} = (idle_{第二次采样} - idle_{第一次采样}) / (CPU_{time第二次采样} - CPU_{time第一次采样}) * 100 CPUusage=(idle第二次采样−idle第一次采样)/(CPUtime第二次采样−CPUtime第一次采样)∗100
-
-
CPU温度的获取:
cpu温度存储在
/sys/class/thermal/thermal_zone0/temp
中,读取出的数值需要除以1000。 -
bash 工具:
cat
:工具用来强制读取一个文件。gerp
:工具用来筛选数据。awk
:用来处理数据。uptime
:获取cpu负载信息
-
bash 数值计算:
bash中的数值计算比较方便的方式是双小括号:
num=0 ((num++)) # 在双小括号中可以正常使用C语言的数值计算语法 echo ${num} # 结果输出--------------- 1
-
-
代码
#!/bin/bash
time_and_load=`date +"%Y-%m-%d__%H:%M:%S "``uptime | tr -s " " "\n" | tr -s "," " " | awk NF | tail -3 | tr -s "\n" " "`
# 0.5s 前
# 开机后总时间
cpu_local1=`cat /proc/stat | grep -w "cpu" | awk '{printf("%d", $2 + $3 + $4 + $5 + $6 + $7 + 8);}'`
# 开机后累计空闲
cpu_idle1=`cat /proc/stat | grep -w "cpu" | awk '{printf("%d", $5);}'`
sleep 0.5s
# 0.5s 后
# 开机后总时间
cpu_local2=`cat /proc/stat | grep -w "cpu" | awk '{printf("%d", $2 + $3 + $4 + $5 + $6 + $7 + 8);}'`
# 开机后累计空闲
cpu_idle2=`cat /proc/stat | grep -w "cpu" | awk '{printf("%d", $5);}'`
# 0.5s 内
((cpu_local = $cpu_local2 - $cpu_local1))
((cpu_idle = $cpu_idle2 - $cpu_idle1))
# 计算cpu占用率
cpu_occu=`echo "$cpu_local $cpu_idle" | awk '{printf("%.2f%%", (1 - $2 / $1) * 100);}'`
# CPU温度
cpu_temp_info=`cat /sys/class/thermal/thermal_zone0/temp | awk '{
if ($1 >= 1000 && $1 < 50000) {
printf("%.2f normal", $1 / 1000);
}
else if ($1 >= 50000 && $1 <= 70000) {
printf("%.2f note", $1 / 1000);
}
else {
printf("%.2f warning", $1 / 1000);
}
}'`
echo "${time_and_load}${cpu_occu} ${cpu_temp_info}"