线程死循环导致单核cpu满载,需按“进程→线程→栈帧”顺序排查:先用top -1或mpstat确认单核%usr持续近100%,再用top -h找高cpu线程tid,转十六进制后用jstack/pstack定位死循环代码行。

线程死循环导致单核CPU满载,本质是某个线程持续占用一个CPU核心,不主动让出时间片。排查关键在于“从进程到线程,再到栈帧”,跳过猜测,直击执行点。
第一步:确认单核是否真被占满
不要只看整体CPU使用率。运行以下命令,观察各核心实时负载:
- top → 按数字键 1:切换显示所有CPU核心,找持续显示 99%–100% 的那一列(比如 CPU0)
- mpstat -P ALL 1:每秒输出各核详细使用率,重点关注 %usr(用户态)是否长期接近100%,而非 %wa(IO等待)或 %sy(内核态)
- 若仅一核飙高而其他核空闲,基本可锁定为某线程在该核上死循环,不是整体负载问题
第二步:定位高CPU线程及其所属进程
找到那个“钉”在某个核上的线程ID(TID),再反查它属于哪个进程:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 用 top -H 查看所有线程(-H 表示显示线程模式)
- 按 P 键确保按CPU排序,记下最顶部的 PID 列数值(注意:此时PID列实际是TID)
- 用 ps -p
-o pid,ppid,comm,args 反查该线程归属的进程名和主进程PID - 也可直接用 ps -eo tid,pid,comm,%cpu --sort=-%cpu | head -10 一次性列出CPU最高的前10个线程及对应进程
第三步:把线程ID转成十六进制,用于栈分析
Linux内核和JVM调试工具(如jstack)中,线程标识默认用十六进制表示,必须转换才能匹配:
- 执行 printf "%x\n"
,例如 TID=28472 → 输出 6f38 - 这一步不能跳过,十进制TID在jstack或pstack输出里是搜不到的
- 若进程是Java应用,立即执行 jstack
| grep -A20 "6f38" ,查看该线程正在执行哪一行代码、是否卡在while(true)、无限递归或忙等待 - 若为C/C++/Go等原生程序,可用 pstack
或 gdb -p 后输入 thread apply all bt 查所有线程调用栈,聚焦TID对应的栈顶函数
第四步:验证与收尾
确认死循环后,需判断能否安全终止,并防止复发:
- 先尝试 kill -15
让进程自行清理;若5秒后仍存在,再用 kill -9 - 检查该进程启动方式:是否由systemd管理?若是,用 systemctl status
看日志,确认崩溃前是否有异常提示 - 临时规避后,务必回溯代码:检查循环条件是否恒真、锁是否未释放、计时器是否失效、外部依赖返回异常值导致逻辑绕过退出分支










