17

我有一个似乎陷入僵局的过程:

# strace -p 5075
Process 5075 attached - interrupt to quit
futex(0x419cf9d0, FUTEX_WAIT, 5095, NULL

它坐在“futex”系统调用上,似乎无限期地等待锁。当“top”运行时,该进程显示消耗大量 CPU:

# top -b -n 1
top - 23:13:18 up 113 days,  4:19,  1 user,  load average: 1.69, 1.74, 1.72
Tasks: 269 total,   1 running, 268 sleeping,   0 stopped,   0 zombie
Cpu(s):  8.1%us,  0.1%sy,  0.0%ni, 91.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  12165696k total,  3810476k used,  8355220k free,    29440k buffers
Swap:  8388600k total,    43312k used,  8345288k free,   879988k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
5075 omdb      18   0 2373m 1.7g  26m S 199.7 14.9 102804:11 java

该进程也显示为处于“S” - 睡眠状态,如果它正在等待某些资源,这是有道理的。但是,我不明白如果进程处于睡眠状态,为什么 CPU 利用率会接近 200%。为什么 top 在睡眠进程中报告如此高的 CPU 使用率?它的 CPU 利用率不应该为零吗?

4

4 回答 4

9

top报告的 CPU 使用率与进程状态之间没有关联。手册页说(强调我的):

%CPU -- CPU 使用率

自上次屏幕更新以来任务占用的 CPU 时间份额,以占总 CPU 时间的百分比表示。

因此,自上次屏幕更新以来,您的进程确实使用了大量的处理器时间。是的,它正在休眠,但那是因为当前正在运行的进程是top它本身(这是有道理的,因为它当前正在更新屏幕)。

于 2012-05-16T23:28:49.987 回答
4

top输出完全正常。

平均负载计算包括等待某物的进程(互斥体/futexes、IO 等)以及实际使用 CPU 的进程。比如说,运行类似的东西来测试它:

dd if=/dev/sda of=/dev/null

并观察最高输出,看看会发生什么。它将平均负载增加 1。

如果你看这一行:

Cpu(s):  8.1%us,  0.1%sy,  0.0%ni, 91.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

“91.8%id”中的“id”表示“空闲”。所以CPU实际上并没有做太多事情。

于 2012-05-16T23:29:33.377 回答
4

您的应用程序是否分叉子进程?strace 输出可能表明主进程只是在等待子进程完成它们的工作。如果是这样,您可以尝试运行

strace -f -p 5075

也可以跟踪子进程。

于 2013-06-25T23:57:12.390 回答
0

让我加两分钱。

顶部显示进程在特定时刻的状态。但这并不意味着该进程一直处于该状态。

这个建议是完全错误的。

该过程可以在前一个最高时刻和当前最高时刻之间在 R 和 S 状态之间切换数百万次,因此如果进程在 R 和 S 状态之间快速切换,您可以轻松地将其捕获到 S 状态。

但是,它在切换之间使用 CPU 时间。

所以请感受一下 cpu_usage 事物(它描述了一段时间)和 state 事物(它描述了一个特定的时刻)之间的区别。

让我举一个清楚的例子。

有人在过去 10 分钟内从您的口袋里偷走了 3 个苹果。

但是,现在它不会从你的口袋里偷苹果。

偷苹果 = cpu_usage,这个人现在没有偷苹果的事实 = 进程状态

那么,得到一个特征并试图预测另一个特征是完全错误的。

于 2020-05-08T20:01:26.370 回答