[Study] top是如何实现的?

Linux中的top命令是如何实现的?

初探

top是procs的一部分, 常用来查看系统的负载情况. procs中除了top外, 还包括ps, free, w, uptime, watch, sysctl等常用的命令. 了解top命令除了直接在terminal使用之外, 就是top的官方文档源代码了.
不过在此之前, 我们可以用strace top看下运行top命令时到底做了什么?

  1. 首先会读取一系列以依赖文件
  2. 然后会读取一些系统配置信息
  3. 最后就是从/proc目录下读取进程的statm信息

/proc/xxx/statm

[cal@manjaro-nuc10i7fnh ~]$ cat /proc/self/statm
2126 130 114 6 0 112 0

2126 a)进程占用的总的内存
130 b)进程当前时刻占用的物理内存
114 c)同其它进程共享的内存
6 d)进程的代码段
0 e)共享库(从2.6版本起,这个值为0)
112 f)进程的堆栈
0 g)dirty pages(从2.6版本起,这个值为0)

源代码实现

太久没碰过C语言了, 看着吃力. 先挖个坑, 先记个参考资料 https://blog.csdn.net/ubuntu2016/article/details/79439658

简单验证idle rate的计算逻辑

https://stackoverflow.com/questions/23367857/accurate-calculation-of-cpu-usage-given-in-percentage-in-linux
https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk65143

使用脚本读取并计算当前的cpu idle.

[cal@manjaro-nuc10i7fnh ~]$ cat calc_cpu_usage.sh 
#!/bin/bash 
while :; do
  # Get the first line with aggregate of all CPUs 
  cpu_now=($(head -n1 /proc/stat)) 
  # Get all columns but skip the first (which is the "cpu" string) 
  cpu_sum="${cpu_now[@]:1}" 
  # Replace the column seperator (space) with + 
  cpu_sum=$((${cpu_sum// /+})) 
  # Get the delta between two reads 
  cpu_delta=$((cpu_sum - cpu_last_sum)) 
  # Get the idle time Delta 
  cpu_idle=$((cpu_now[4]- cpu_last[4])) 
  # Calc percentage 
  cpu_usage=$((100 * cpu_idle / cpu_delta)) 
  
  # Keep this as last for our next read 
  cpu_last=("${cpu_now[@]}") 
  cpu_last_sum=$cpu_sum 
  
  echo "CPU idle rate at $cpu_usage%" 
  
  # Wait a second before the next read 
  sleep 1 
done

对比CPU压力测试前后的idle, 可以确认top的计算方式和上面的脚本一致.

  • 没有压力测试
  • stress --cpu 6
  • stress --cpu 12
posted @ 2020-05-24 23:33  changediff  阅读(2887)  评论(0编辑  收藏  举报