我正在尝试编写一个脚本来返回特定进程的CPU使用率(以百分比为单位),我需要使用/ proc / PID / stat,因为嵌入式系统上不存在ps aux。
我尝试了这个:
#!/usr/bin/env bash
PID=$1
PREV_TIME=0
PREV_TOTAL=0
while true;do
TOTAL=$(grep '^cpu ' /proc/stat |awk '{sum=$2+$3+$4+$5+$6+$7+$8+$9+$10; print sum}')
sfile=`cat /proc/$PID/stat`
PROC_U_TIME=$(echo $sfile|awk '{print $14}')
PROC_S_TIME=$(echo $sfile|awk '{print $15}')
PROC_CU_TIME=$(echo $sfile|awk '{print $16}')
PROC_CS_TIME=$(echo $sfile|awk '{print $17}')
let "PROC_TIME=$PROC_U_TIME+$PROC_CU_TIME+$PROC_S_TIME+$PROC_CS_TIME"
CALC="scale=2 ;(($PROC_TIME-$PREV_TIME)/($TOTAL-$PREV_TOTAL)) *100"
USER=`bc <<< $CALC`
PREV_TIME="$PROC_TIME"
PREV_TOTAL="$TOTAL"
echo $USER
sleep 1
done
但是,如果我将其与顶部进行比较,则不会给出正确的值。你们中有人知道我在哪里犯错吗?
谢谢
在正常调用top
(无参数)的情况下,该%CPU
列是一段时间内进程使用的滴答声与一个CPU提供的总滴答声的比例。
从top.c源中,该%CPU
字段的计算公式为:
float u = (float)p->pcpu * Frame_tscale;
其中,进程的pcpu是自上次显示以来经过的用户时间+系统时间:
hist_new[Frame_maxtask].tics = tics = (this->utime + this->stime);
...
if(ptr) tics -= ptr->tics;
...
// we're just saving elapsed tics, to be converted into %cpu if
// this task wins it's displayable screen row lottery... */
this->pcpu = tics;
和:
et = (timev.tv_sec - oldtimev.tv_sec)
+ (float)(timev.tv_usec - oldtimev.tv_usec) / 1000000.0;
Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : Cpu_tot));
Hertz
在大多数系统(grep 'define HZ' /usr/include/asm*/param.h
)上为100 ticks / second ,et
是自上一帧显示以来经过的时间(以秒为单位),并且Cpu_tot
是CPU的数量(但默认为1)。
因此,在每秒T秒钟的过程中,每秒使用100个滴答的系统上的等式为:
(curr_utime + curr_stime - (last_utime + last_stime)) / (100 * T) * 100
脚本变为:
#!/bin/bash
PID=$1
SLEEP_TIME=3 # seconds
HZ=100 # ticks/second
prev_ticks=0
while true; do
sfile=$(cat /proc/$PID/stat)
utime=$(awk '{print $14}' <<< "$sfile")
stime=$(awk '{print $15}' <<< "$sfile")
ticks=$(($utime + $stime))
pcpu=$(bc <<< "scale=4 ; ($ticks - $prev_ticks) / ($HZ * $SLEEP_TIME) * 100")
prev_ticks="$ticks"
echo $pcpu
sleep $SLEEP_TIME
done
这种方法与原始脚本的主要区别在于top是针对1个CPU计算其CPU时间百分比,而您试图针对所有CPU的总计计算该时间百分比。确实可以通过执行来计算一段时间内的确切总滴答Hertz * time * n_cpus
,并且/ proc / stat中的数字不一定能正确求和:
$ grep 'define HZ' /usr/include/asm*/param.h
/usr/include/asm-generic/param.h:#define HZ 100
$ grep ^processor /proc/cpuinfo | wc -l
16
$ t1=$(awk '/^cpu /{sum=$2+$3+$4+$5+$6+$7+$8+$9+$10; print sum}' /proc/stat) ; sleep 1 ; t2=$(awk '/^cpu /{sum=$2+$3+$4+$5+$6+$7+$8+$9+$10; print sum}' /proc/stat) ; echo $(($t2 - $t1))
1602
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句