记最近Linux中遇到cpu使用率低loadavg高的分析过程
2021/7/23 7:10:33
本文主要是介绍记最近Linux中遇到cpu使用率低loadavg高的分析过程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
首先明确一下CPU使用率和loadavg这两个概念:
CPU使用率
指当前CPU正在执行指令的繁忙程度,越高表面CPU正在执行很多指令即有进程一直在cpu上运行着
Loadavg
指的是CPU负载程度,表明的是CPU当前正在运行的任务以及等待运行的任务统计,是一种趋势的体现;更详细一点来说是R和D状态的进程数量统计
分析此问题的起因是前一段时间购买的开发板,使用最新的SDK跑起来后,几乎没有什么任务在运行,CPU 100% idle,但是loadavg一直在1以上(cpu是双核A7),对比之前使用过的单核MIPS架构路由器来说,显得非常不正常。
在分析开始之前,先要介绍几个工具:
top:查看进程状态以及CPU占用和loadavg参数
ps -aux: 查看进程cpu占用和运行状态
vmstat:查看cpu户空间和内核空间占用情况及系统中断和上下文切换状态
pidstat:查看具体某个进程对cpu占用和上下文切换状态
iostat:查看系统IO负载状态
首先看一下系统状态:
root@wireless-tag:/# vmstat -w 1
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 75660 3948 11740 0 0 0 0 57 108 2 6 91 0 0
0 0 0 75664 3948 11740 0 0 0 0 58 51 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 43 49 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 45 56 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 46 53 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 46 57 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 43 52 0 0 100 0 0
0 0 0 75664 3948 11740 0 0 0 0 42 49 0 0 100 0 0
cpu 100% idle: 说明几乎没有进程在使用cpu,中断以及上下文切换也很低
r及b队列数量为0
root@wireless-tag:/# iostat
Linux 4.9.84 (wireless-tag) 01/01/70 _armv7l_ (2 CPU)avg-cpu: %user %nice %system %iowait %steal %idle
0.57 0.00 1.73 0.02 0.00 97.68Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mtdblock0 0.03 0.41 0.00 168 0
mtdblock1 0.03 0.41 0.00 168 0
mtdblock2 0.03 0.41 0.00 168 0
mtdblock3 0.03 0.41 0.00 168 0
mtdblock4 0.03 0.41 0.00 168 0
mtdblock5 0.03 0.41 0.00 168 0
mtdblock6 0.03 0.41 0.00 168 0
mtdblock7 0.03 0.41 0.00 168 0
mtdblock8 0.03 0.41 0.00 168 0
mtdblock9 0.03 0.41 0.00 168 0
mtdblock10 0.02 0.38 0.00 156 0
mtdblock11 0.02 0.38 0.00 156 0
mtdblock12 0.02 0.38 0.00 156 0
ubiblock0_1 0.15 9.66 0.00 3948 0
zram0 0.00 0.01 0.01 4 4
io也几乎都是空闲%idle 97.68
root@wireless-tag:/# uptime
23:03:15 up 4 min, 0 users, load average: 1.10, 0.67, 0.29
但是loadavg 1分钟统计显示1.10,结合前面r和b队列为0,说明系统有进程一直在等待运行
接着看一下进程列表:
root@wireless-tag:/# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.3 1.6 2596 1736 ? Ss 22:58 0:02 /sbin/procd
root 2 0.0 0.0 0 0 ? S 22:58 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 22:58 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 22:58 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 22:58 0:00 [rcu_preempt]
root 8 0.0 0.0 0 0 ? S 22:58 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? S 22:58 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 22:58 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S< 22:58 0:00 [lru-add-drain]
root 12 0.0 0.0 0 0 ? S 22:58 0:00 [watchdog/0]
root 13 0.0 0.0 0 0 ? S 22:58 0:00 [cpuhp/0]
root 14 0.0 0.0 0 0 ? S 22:58 0:00 [cpuhp/1]
root 15 0.0 0.0 0 0 ? S 22:58 0:00 [watchdog/1]
root 16 0.0 0.0 0 0 ? S 22:58 0:00 [migration/1]
root 17 0.0 0.0 0 0 ? S 22:58 0:00 [ksoftirqd/1]
root 18 0.0 0.0 0 0 ? S 22:58 0:00 [kworker/1:0]
root 19 0.0 0.0 0 0 ? S< 22:58 0:00 [kworker/1:0H]
root 20 0.1 0.0 0 0 ? S 22:58 0:00 [kdevtmpfs]
root 21 0.0 0.0 0 0 ? S< 22:58 0:00 [netns]
root 22 0.0 0.0 0 0 ? S 22:58 0:00 [kworker/u4:1]
root 173 0.0 0.0 0 0 ? S 22:58 0:00 [oom_reaper]
root 174 0.0 0.0 0 0 ? S< 22:58 0:00 [writeback]
root 176 0.0 0.0 0 0 ? S 22:58 0:00 [kcompactd0]
root 177 0.0 0.0 0 0 ? S< 22:58 0:00 [crypto]
root 178 0.0 0.0 0 0 ? S< 22:58 0:00 [bioset]
root 180 0.0 0.0 0 0 ? S< 22:58 0:00 [kblockd]
root 201 0.0 0.0 0 0 ? S< 22:58 0:00 [watchdogd]
root 282 0.0 0.0 0 0 ? S 22:58 0:00 [kworker/0:1]
root 296 0.0 0.0 0 0 ? S 22:58 0:00 [kswapd0]
root 297 0.0 0.0 0 0 ? S< 22:58 0:00 [vmstat]
root 384 0.0 0.0 0 0 ? D 22:58 0:00 [ehci_monitor] ----->注意状态为D
root 400 0.0 0.0 0 0 ? S 22:58 0:00 [urdma_tx_thread
root 414 0.0 0.0 0 0 ? S 22:58 0:00 [kworker/1:1]
root 419 0.0 0.0 0 0 ? S 22:58 0:00 [kworker/0:2]
root 502 0.1 0.0 0 0 ? S 22:58 0:00 [ubi_bgt0d]
root 503 0.0 0.0 0 0 ? S< 22:58 0:00 [bioset]
root 508 0.0 0.0 0 0 ? S< 22:58 0:00 [kworker/0:1H]
root 538 0.0 0.0 0 0 ? S< 22:59 0:00 [kworker/1:1H]
root 551 0.0 0.0 0 0 ? S 22:59 0:00 [ubifs_bgt0_2]
root 809 0.0 1.4 2144 1540 ? S 22:59 0:00 /sbin/ubusd
root 812 0.0 1.8 3144 1924 ttyS0 Ss 22:59 0:00 /bin/ash --login
root 859 0.0 0.0 0 0 ? S 22:59 0:00 [ubi_bgt1d]
root 885 0.0 0.0 0 0 ? S 22:59 0:00 [ubifs_bgt1_0]
root 986 0.0 0.0 0 0 ? S< 22:59 0:00 [bioset]
root 996 0.0 0.0 0 0 ? S< 22:59 0:00 [cfg80211]
root 1003 0.0 0.0 0 0 ? S 22:59 0:00 [kworker/u4:2]
root 1226 0.0 1.3 2320 1376 ? S 22:59 0:00 /sbin/logd -S 64
root 1247 0.0 1.4 2780 1560 ? S 22:59 0:00 /sbin/rpcd -s /v
root 1395 0.0 1.5 2396 1664 ? S 22:59 0:00 /sbin/netifd
root 1888 0.0 1.3 2708 1416 ttyS0 R+ 23:10 0:00 ps -aux
发现一个状态为D的内核线程ehci_monitor
关于进程状态说明如下:
进程状态: O:进程正在处理器运行 S:休眠状态(sleeping) R:等待运行(runable)R Running or runnable (on run queue) 进程处于运行或就绪状态 I:空闲状态(idle) Z:僵尸状态(zombie) T:跟踪状态(Traced) B:进程正在等待更多的内存页 D:不可中断的深度睡眠
D状态标示不可中断,同时又是内核线程,说明该线程没有捕获任何信号,不能被中断,一直在CPU运行队列中 ,但是该线程又不占用CPU(前面cpu 100% idle),说明该线程没有在干活。此时我们可以认为,该线程的实现有点”问题“,不干活又一直要运行,可能是在等待什么条件或者检查什么状态亦或其他什么很机密的东西;总之,该线程的状态处理有待改善。
既然已经定位到了内核线程名,那么就没有什么比查看代码来得更直接的了,通过查看代码发现该线程就是在干一个活,总结起来就是每隔100ms查询一个条件,如下:
while(1) { if(check_status) do.... msleep(100); }
该线程没有捕获任何信号,同时又没有改变运行状态,唯有一个msleep会引起调度,最终状态就是D,不可中断;
既然如此,我们来改善一下状态,做两个改变:
1. 设置线程状态为INTERRUPTIBLE
2. 使用schedule_timeout来显示的调度
while(1)
{set_current_state(TASK_INTERRUPTIBLE);
if(check_status)
do....
schedule_timeout(HZ)
}
修改之后结果:
root@wireless-tag:/# uptime
23:51:52 up 0 min, 0 users, load average: 0.16, 0.05, 0.01
root@wireless-tag:/# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 5.9 1.5 2596 1652 ? Ss 23:51 0:02 /sbin/procd
root 2 0.0 0.0 0 0 ? S 23:51 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 23:51 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S 23:51 0:00 [kworker/0:0]
root 5 0.0 0.0 0 0 ? S< 23:51 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 23:51 0:00 [kworker/u4:0]
root 7 0.0 0.0 0 0 ? S 23:51 0:00 [rcu_preempt]
root 8 0.0 0.0 0 0 ? S 23:51 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? S 23:51 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 23:51 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S< 23:51 0:00 [lru-add-drain]
root 12 0.0 0.0 0 0 ? S 23:51 0:00 [watchdog/0]
root 13 0.0 0.0 0 0 ? S 23:51 0:00 [cpuhp/0]
root 14 0.0 0.0 0 0 ? S 23:51 0:00 [cpuhp/1]
root 15 0.0 0.0 0 0 ? S 23:51 0:00 [watchdog/1]
root 16 0.0 0.0 0 0 ? S 23:51 0:00 [migration/1]
root 17 0.0 0.0 0 0 ? S 23:51 0:00 [ksoftirqd/1]
root 18 0.0 0.0 0 0 ? S 23:51 0:00 [kworker/1:0]
root 19 0.0 0.0 0 0 ? S< 23:51 0:00 [kworker/1:0H]
root 20 2.0 0.0 0 0 ? S 23:51 0:00 [kdevtmpfs]
root 21 0.0 0.0 0 0 ? S< 23:51 0:00 [netns]
root 22 0.0 0.0 0 0 ? S 23:51 0:00 [kworker/u4:1]
root 173 0.0 0.0 0 0 ? S 23:51 0:00 [oom_reaper]
root 174 0.0 0.0 0 0 ? S< 23:51 0:00 [writeback]
root 176 0.0 0.0 0 0 ? S 23:51 0:00 [kcompactd0]
root 177 0.0 0.0 0 0 ? S< 23:51 0:00 [crypto]
root 178 0.0 0.0 0 0 ? S< 23:51 0:00 [bioset]
root 180 0.0 0.0 0 0 ? S< 23:51 0:00 [kblockd]
root 201 0.0 0.0 0 0 ? S< 23:51 0:00 [watchdogd]
root 282 1.3 0.0 0 0 ? S 23:51 0:00 [kworker/0:1]
root 296 0.0 0.0 0 0 ? S 23:51 0:00 [kswapd0]
root 297 0.0 0.0 0 0 ? S< 23:51 0:00 [vmstat]
root 384 0.0 0.0 0 0 ? S 23:51 0:00 [ehci_monitor] ----> S态
root 400 0.0 0.0 0 0 ? S 23:51 0:00 [urdma_tx_thread
root 414 0.5 0.0 0 0 ? S 23:51 0:00 [kworker/1:1]
root 419 0.0 0.0 0 0 ? S 23:51 0:00 [kworker/0:2]
root 422 0.0 0.0 0 0 ? S< 23:51 0:00 [bioset]
root@wireless-tag:/# vmstat -w 1
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 76568 3600 11308 0 0 0 0 51 103 4 6 90 0 0
0 0 0 76568 3600 11308 0 0 0 0 56 57 0 0 100 0 0
0 0 0 76584 3600 11308 0 0 0 0 43 56 0 0 100 0 0
0 0 0 76584 3600 11308 0 0 0 0 43 53 0 0 100 0 0
0 0 0 76584 3600 11308 0 0 0 0 44 59 0 0 100 0 0
结果显示很“完美”
关于内核线程的使用以及线程状态切换和维护,后面有时间再补充一篇博文,以便更强有力的说明CPU使用率和loadavg这两个参数的意义。
同时我们也能得出结论:CPU够不够用,系统压力大不大,不能单纯的只看使用率或者loadavg,需要两个相结合来分析。
这篇关于记最近Linux中遇到cpu使用率低loadavg高的分析过程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-18git仓库有更新,jenkins 自动触发拉代码怎么配置的?-icode9专业技术文章分享
- 2024-12-18Jenkins webhook 方式怎么配置指定的分支?-icode9专业技术文章分享
- 2024-12-13Linux C++项目实战入门教程
- 2024-12-13Linux C++编程项目实战入门教程
- 2024-12-11Linux部署Scrapy教程:新手入门指南
- 2024-12-11怎么将在本地创建的 Maven 仓库迁移到 Linux 服务器上?-icode9专业技术文章分享
- 2024-12-10Linux常用命令
- 2024-12-06谁看谁服! Linux 创始人对于进程和线程的理解是…
- 2024-12-04操作系统教程:新手入门及初级技巧详解
- 2024-12-04操作系统入门:新手必学指南