当前位置:首页>Linux>Linux - 查看进程的瞬时CPU使用率

Linux - 查看进程的瞬时CPU使用率

  • 2026-09-05 10:15:51
Linux - 查看进程的瞬时CPU使用率
概述
在使用 Linux 作为应用服务器时,若想要查看应用服务器的进程的 CPU 使用率,观察应用的 CPU 使用率是否是并发的限制条件

方式一:top命令基础班
概述

top 命令是最熟悉、最基础的查看进程对资源占用情况的命令

示例
## 参数解析## -p 2336:仅展示PID为2336的进程信息## -c:展示COMMAND的值时,不展示进程名称,而是展示启动进程的启动命令top -p 2336 -c
优点

top 命令被大众熟悉,起手简单

缺点
  • top 命令会采集 CPU 资源信息、内存资源信息、进程信息等大量信息,底层需要读取的文件多、还需要维护状态,属于重量级操作,在初始化时会占用大量 CPU 资源

  • top 命令对进程 CPU 使用率的第一次采样数据是不准确的:top 命令在获取进程 CPU 使用率时,底层是通过读取 /proc/进程PID/stat 文件内容来计算的。但是这个文件是系统自身维护的,记录的是进程自启动以来的 CPU 信息,所以只有在 3 秒刷新后的第二次采样结果才是正确的

应用场景

由于 top 命令会采集大量信息,属于重量级操作,在初始化时会占用大量 CPU。这种特性对应用服务产生影响相对较大,不适于进行实时监控、日志采集等的高频场景,但是现场排查问题还是很适合的,毕竟操作非常简单、获取到的信息量又大


方式二:top命令进阶版
概述

在 top 命令的基础上加参数、加计算,过滤掉第一次结果,仅获取第二次开始的进程信息

示例
## 参数解析## LC_ALL=C:强制使用C语言环境,确保程序输出的格式是英文且可预测## top:命令## -p 2336:仅展示PID为2336的进程信息## -b:top命令的参数,表示非交互式## -n3:top命令的参数,表示执行2次采样输出结果后退出## -d1:top命令的参数,表示采样之间的间隔时间,单位为秒## -c:展示COMMAND的值时,不展示进程名称,而是展示启动进程的启动命令## awk '/^top -/ { frame++ } frame >= 2 { print }'##     awk:系统自带的一个强大的文本处理工具,专门用于按行分析、提取和处理结构化文本数据##         命令格式:awk '模式 {动作}'##                  模式:对哪些行执行操作,可省略##                  动作:对匹配行做什么##         命令结果:对匹配行将以空格进行分割,以格式 $num 可以获取到每一个分割部分,num从1开始##     /^top -/:匹配以 top - 开头的行##     { frame++ }:每匹配到一行时,对变量frame的值加一##     frame >= 2 { print }:当变量frame的值大于等于2时,打印从匹配行开始的后续所有行LC_ALL=C top -p 2336 -bn3 -d1 -c | awk '/^top -/ { frame++ } frame >= 2 { print }'
优点
  • 基于 top 命令,起手简单
  • 过滤掉了第一次采样的不准确的数据
缺点

top 命令会采集 CPU 资源信息、内存资源信息、进程信息等大量信息,底层需要读取的文件多、还需要维护状态,属于重量级操作,在初始化时会占用大量 CPU 资源


方式三:命令脚本
概述

前面讲了 top 命令,该命令底层是通过获取 /proc/进程PID/stat 文件内容来计算 CPU 使用率的,那么 /proc/进程PID/stat 文件是什么呢

/proc/进程PID/stat 文件是每个进程的内核级统计信息文件,包含 CPU 时间、状态、内存等。超级管理员可以访问所有用户拥有的进程的这些文件,但是普通用户只能访问自身拥有的进程的对应的文件

文件内容完整示例
  • 文件内容的格式是固定的,以空格进行隔开。下面讲解以空格隔开后的一些关键位置的数据

  • $1:进程 ID

  • $2:进程名称

  • $3:进程状态

    • R:运行 / 可运行

    • S:睡眠

    • D:不可中断睡眠

    • Z:僵尸

    • T:停止

  • $4:父进程 ID

  • $5:进程组 ID

  • $6:会话 ID

  • $14:用户态 CPU 时间

  • $15:内核态 CPU 时间

  • $20:线程数

  • $21:进程启动至今时间

命令脚本示例
#!/bin/bash# 检查是否传入了PID参数if [ $# -ne 1 ] || ! [[ $1 =~ ^[0-9]+$ ]]; then    echo "请传入正确格式的PID" >&2    exit 1fi# 传入的进程IDPID=$1# 采样间隔,设置为1秒INTERVAL=1# 检查 /proc/$PID/stat 是否存在if [ ! -f "/proc/$PID/stat" ]; then    echo "进程不存在" >&2    exit 1fi# 第一次采样if stat_line=$(cat "/proc/$PID/stat" 2>/dev/null); then    # 将变量的内容按照预定的IFS的值进行分割    set -- $stat_line    # 记录用户态CPU时间、内核态CPU时间的总和,若某一个位置没有则默认为0    cpu1=$((${14:-0} + ${15:-0}))else    echo "错误:无法读取 /proc/$PID/stat 文件内容(第一次采样)" >&2    exit 1fi# 睡眠sleep "$INTERVAL"# 第二次采样if stat_line=$(cat "/proc/$PID/stat" 2>/dev/null); then    # 将变量的内容按照预定的IFS的值进行分割    set -- $stat_line    # 记录用户态CPU时间、内核态CPU时间的总和,若某一个位置没有则默认为0    cpu2=$((${14:-0} + ${15:-0}))else    echo "错误:无法读取 /proc/$PID/stat 文件内容(第二次采样)" >&2    exit 1fi# 计算两次记录值之间的差值delta=$((cpu2 - cpu1))if [ $delta -lt 0 ]; then    delta=0fi# 获取进程名称cmd=""# 1. 优先获取启动进程的完整命令if [ -f "/proc/$PID/cmdline" ]; then	cmd=$(tr '\0' ' ' < "/proc/$PID/cmdline" 2>/dev/null)	cmd=$(echo "$cmd" | sed 's/ $//')fi# 2. 若没有获取到启动进程的完整命令,则获取进程名称if [ -z "$cmd" ] && [ -f "/proc/$PID/comm" ]; then	cmd=$(cat "/proc/$PID/comm" 2>/dev/null | tr -d '\n')fi# 3. 若没有获取到启动进程的完整命令、也没有获取到进程名称,则直接使用PIDif [ -z "$cmd" ]; then	cmd="[$PID]"fi# 根据差值和间隔时间计算平均CPU使用率cpu_pct=$(awk "BEGIN {printf \"%.1f\", $delta / $INTERVAL}")# 格式化输出打印printf "PID:%-8s CPU:%6s%% CMD:%s\n" "$PID" "$cpu_pct" "$cmd"
优点

直接从底层文件入手来计算 CPU 使用率,性能高、资源占用少、最灵活

缺点

需要自己写脚本,对开发人员、维护人员要求高

应用场景

现场问题排查使用此种方式不合适、耗时太久,但是非常适用于实时监控、日志采集等高频场景


最终结论

现场排查问题,推荐使用 top 命令;高效、高频获取 CPU 使用率时,推荐使用命令脚本

最新文章

随机文章