<p>PSUtil、htop、mpstat等都是从<code>/proc/stat</code>读取以<code>"cpu"</code>开头的行(实际上是第一行),然后根据该行中的值计算一个百分比。您可以在<code>man 5 proc</code>(搜索“proc/stat”)中找到该行中值的含义。在</p>
<p>这也是您提到的<code>grep cpu /proc/stat | awk ....</code>命令的作用。但是<code>/proc/stat</code>中的值代表自上次启动以来花费的时间!也许过了一段时间,我不确定,但关键是这些数据是经过很长时间测量的。在</p>
<p>因此,如果您运行该命令,并在几秒钟(分钟甚至数小时)后再次运行它,它们不会有太大的变化!这就是为什么你看到它总是返回5.12。在</p>
<p>像<code>top</code>这样的程序会记住以前的值,并从新读取的值中减去它们。根据这个结果,可以计算出一个实际反映最近CPU负载的“实时”百分比。在</p>
<p>为了尽可能简单地在python中执行类似的操作,但不运行外部命令来读取<code>/proc/stat</code>并为我们进行计算,我们可以将读取的值存储到一个文件中。下一次运行时,我们可以读回它们,并从新值中减去它们。在</p>
<pre><code>#!/usr/bin/env python2.7
import os.path
# Read first line from /proc/stat. It should start with "cpu"
# and contains times spent in various modes by all CPU's totalled.
#
with open("/proc/stat") as procfile:
cpustats = procfile.readline().split()
# Sanity check
#
if cpustats[0] != 'cpu':
raise ValueError("First line of /proc/stat not recognised")
#
# Refer to "man 5 proc" (search for /proc/stat) for information
# about which field means what.
#
# Here we do calculation as simple as possible:
# CPU% = 100 * time_doing_things / (time_doing_things + time_doing_nothing)
#
user_time = int(cpustats[1]) # time spent in user space
nice_time = int(cpustats[2]) # 'nice' time spent in user space
system_time = int(cpustats[3]) # time spent in kernel space
idle_time = int(cpustats[4]) # time spent idly
iowait_time = int(cpustats[5]) # time spent waiting is also doing nothing
time_doing_things = user_time + nice_time + system_time
time_doing_nothing = idle_time + iowait_time
# The times read from /proc/stat are total times, i.e. *all* times spent
# doing things and doing nothing since last boot.
#
# So to calculate meaningful CPU % we need to know how much these values
# have *changed*. So we store them in a file which we read next time the
# script is run.
#
previous_values_file = "/tmp/prev.cpu"
prev_time_doing_things = 0
prev_time_doing_nothing = 0
try:
with open(previous_values_file) as prev_file:
prev1, prev2 = prev_file.readline().split()
prev_time_doing_things = int(prev1)
prev_time_doing_nothing = int(prev2)
except IOError: # To prevent error/exception if file does not exist. We don't care.
pass
# Write the new values to the file to use next run
#
with open(previous_values_file, 'w') as prev_file:
prev_file.write("{} {}\n".format(time_doing_things, time_doing_nothing))
# Calculate difference, i.e: how much the number have changed
#
diff_time_doing_things = time_doing_things - prev_time_doing_things
diff_time_doing_nothing = time_doing_nothing - prev_time_doing_nothing
# Calculate a percentage of change since last run:
#
cpu_percentage = 100.0 * diff_time_doing_things/ (diff_time_doing_things + diff_time_doing_nothing)
# Finally, output the result
#
print "CPU", cpu_percentage, "%"
</code></pre>
<p>这是一个与<code>top</code>不同的版本,它每秒打印CPU使用率,在变量中而不是在文件中记住先前测量的CPU时间:</p>
^{pr2}$