每隔一段时间(每隔几天)我就注意到一个进程正在使用100%的CPU.这个过程是由Arduino IDE开始的,在某些情况下,我无法重现只是坐在那里100%的CPU,如上图所示.
可能的情况是上传到Arduino板,并且在此过程中电路板断开连接.
我在处理器中有8个内核,因此其中一个内存最大化并不是很明显.事实上,只有连续几次发生它才会变得明显,然后我在100%CPU时可能有3个核心.
有没有办法对此进行一些后台任务检查(比方说,每15分钟一次),然后以某种方式提醒我(例如,某些弹出对话框)?我正在使用Ubuntu 14.04 LTS.
感谢MelBurslan的回答,但我很难过为什么它没有完全正常工作.我目前的脚本是这样的:
cpupercentthreshold=2
pstring=""
top -b -n 1 | sed -e "1,7d" | while read line; do
cpuutil=$(echo ${line} | awk '{print $9}' | cut -d"." -f 1)
procname=$(echo ${line} | awk '{print $12}' )
if [ ${cpuutil} -ge ${cpupercentthreshold} ]
then
echo ${cpuutil}
pstring=${pstring}${procname}" "
echo pstring is currently ${pstring}
fi
done
echo pstring is ${pstring}
if [ -n "${pstring}" ]
then
zenity --title="Warning!" --question --text="These processes are above CPU threshold limit ${pstring}" --ok-label="OK"
fi
我放下了门槛进行测试.但是你可以看到它收集各个进程OK,但最后的测试(显示对话框)失败,因为pstring突然变空,原因我看不到:
13
pstring is currently VirtualBox
6
pstring is currently VirtualBox Xorg
6
pstring is currently VirtualBox Xorg compiz
6
pstring is currently VirtualBox Xorg compiz ibus-engin+
6
pstring is currently VirtualBox Xorg compiz ibus-engin+ top
pstring is
解决方法:
在阅读了MelBurslan的回答和各种评论之后,我决定尝试(受他们的建议启发)在Lua中做一个版本.这是在Lua 5.1.5完成的 – 我不确定它是否适用于最新的Lua.
一般的想法是使用Lua的popen(打开管道)来执行top,然后使用正则表达式(或模式,在Lua中调用)处理结果数据.然后考虑匹配线(其中大多数)超过阈值百分比.如果他们这样做,他们会被添加到表格中.
如果表不为空,则调用zenity以向用户显示消息.我在开发过程中发现了一些“陷阱”:
>我为zenity添加了60秒的超时时间,这样,如果您当时不在PC,则不会在屏幕上显示警告对话框.
>我添加了–display =:0.0,以便在cron下运行时找到显示屏幕.
>我简化了crontab中“每15分钟”的测试,如下所示:
*/15 * * * * /home/nick/check_cpu_usage.lua
>正则表达式从顶部捕获所有内容,以防您想要进行其他测试(例如,使用太多内存).
我认为这比启动大量进程和子shell更快.它似乎工作正常.通过降低阈值(例如,到5)进行测试,并更改crontab条目以检查每分钟.
check_cpu_usage.lua
#! /usr/local/bin/lua
THRESHOLD = 90 -- percent
-- pipe output of top through a file "f"
f = assert (io.popen ("top -b -n 1 -w 512"))
t = { }
-- check each line
for line in f:lines() do
-- match top output, eg.
-- PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
-- 30734 nick 20 0 6233848 3.833g 3.731g S 8.6 12.2 3:11.75 VirtualBox
local pid, user, priority, nice, virt, res, shr,
status, cpu, mem, time, command =
string.match (line,
"^%s*(%d+)%s+(%a+)%s+(%-?%d+)%s+(%-?%d+)" ..
-- pid user priority nice
"%s+([%d.]+[g]?)%s+([%d.]+[g]?)%s+([%d.]+[g]?)%s+([DRSTZ])%s+(%d+%.%d+)%s+(%d+%.%d+)" ..
-- virtual res shr status %cpu %mem
"%s+([0-9:.]+)%s+(.*)$")
-- time command
-- if a match (first few lines won't) check for CPU threshold
if pid then
cpu = tonumber (cpu)
if cpu >= THRESHOLD then
table.insert (t, string.format ("%s (%.1f%%)", command, cpu))
end -- if
end -- if
end -- for loop
f:close()
-- if any over the limit, alert us
if #t > 0 then
os.execute ('zenity --title="CPU usage warning!" --info ' ..
'--text="These processes are using more than ' ..
THRESHOLD .. '% CPU:\n' ..
table.concat (t, ", ") ..
'" --ok-label="OK" ' ..
'--timeout=60 ' .. -- close dialog after one minute in case we aren't around
'--display=:0.0 ' -- ensure visible when running under cron
)
end -- if