根据这个参考,一个进程有以下状态
R running or runnable (on run queue)
D uninterruptible sleep (usually IO)
S interruptible sleep (waiting for an event to complete)
Z defunct/zombie, terminated but not reaped by its parent
T stopped, either by a job control signal or because it is being traced
在睡眠状态下,进程不会消耗 CPU 时间,但是在下面的输出中,我看到一个进程使用了 100% 的 CPU,同时它处于 S 状态。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32643 root 20 0 13736 7748 472 R 98 0.0 2:59.30 bzip2
29504 satam 20 0 1063m 779m 3824 S 100 2.4 1242:54 stencil
31923 root 20 0 15092 1224 848 D 14 0.0 1:39.96 find
这怎么可能?这意味着什么?
答案1
“不可中断睡眠”意味着进程正在等待 I/O(例如磁盘操作)。但是,如果 CPU 正在运行该进程,即使它没有工作,CPU 仍然“卡住”等待它完成 io,以便它可以继续执行其他任务 - 安排另一项任务。因此,当进程处于 D 模式时,这会消耗 100% 的 CPU 周期。
因此它处于睡眠模式,此时它不执行任何 CPU 工作,但不可中断,这意味着 CPU 不能执行任何其他操作。
在多核系统中,其他核心可用于执行其他任务。
答案2
我们来看一看图片:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29504 satam 20 0 1063m 779m 3824 S 100 2.4 1242:54 stencil
该进程处于“S”状态,但 CPU 使用率 = 100%。
虽然这没有任何意义,但是我们现在就会找到它。
“Top” 显示的是当前进程的状态。它是特定时间点的特征。因此,进程“当前”处于休眠状态。
但是 CPU 使用率不是时间实例的特征,而是时间间隔的特征。它是从现在到之前某个时间之间的时间间隔内的平均 CPU 使用率:从 (t-delta) 到 t。其中 t 是当前时刻。
因此,现在该进程处于休眠状态,其 CPU 使用率为 0%。但是(例如)1 秒前,该进程的 CPU 使用率为 100%。因此,top 进行计算:(100%+0%)/1s = 100%。
是否有意义?
因此,“S” 是当前进程的状态。但 CPU 使用率列是从现在到之前某个时间的平均 CPU 使用率。这就是它的意义所在。
让我再举一些例子:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
11568 vasya 20 0 28,558g 175004 92304 S 5,6 1,1 10:33.09 chrome
Chrome 处于“S”状态,但 top 显示它使用了 5.6% 的 CPU。这毫无意义。处于“S”状态的进程怎么会消耗 CPU?对吧?其实这很有道理。
该进程现在处于“S”状态。但是之前它处于“R”状态。
看,让我们快速检查一下 chrome 的状态:
$ while true; do cat /proc/11568/stat | awk '{print $3}'; done
S
S
R
S
S
S
S
S
S
S
S
R
S
S
大多数情况下,chrome 处于“S”状态,因此“top”很有可能会从 procfs 读取“S”状态并显示给我们。但这并不意味着 chrome 一直处于“S”状态,正如您所见。
因此,如果在时间点 = 0 秒时 CPU 使用率为 5.6%(状态“R”),而在下一时间点 =1 秒时 CPU 使用率为 0%(状态“S”),则进行计算以找出平均值 => (5.6%+0)/(1-0) = 5.6%
该进程现在处于休眠状态。(“S”列)。但是 CPU 使用率与当前特性无关。它是进程在过去三秒内 CPU 使用率的平均值。(默认情况下,top 每三秒刷新一次)。
希望它能够澄清这个话题。