将某些进程限制为CPU%-Linux
我有以下问题:一些动态生成的进程有消耗100%CPU的倾向。我想将所有符合某些标准(例如进程名)的进程限制在一定的CPU百分比范围内 我试图解决的具体问题是治理folding@home辅助进程。我能想到的最好的解决方案是一个perl脚本,它定期执行,并使用cpulimit实用程序来限制进程(如果您对更多细节感兴趣,请查看这个)。它是有效的,但它是一个黑客:/ 有什么想法吗?我想让操作系统来处理进程:)将某些进程限制为CPU%-Linux,linux,limit,cpu,Linux,Limit,Cpu,我有以下问题:一些动态生成的进程有消耗100%CPU的倾向。我想将所有符合某些标准(例如进程名)的进程限制在一定的CPU百分比范围内 我试图解决的具体问题是治理folding@home辅助进程。我能想到的最好的解决方案是一个perl脚本,它定期执行,并使用cpulimit实用程序来限制进程(如果您对更多细节感兴趣,请查看这个)。它是有效的,但它是一个黑客:/ 有什么想法吗?我想让操作系统来处理进程:) 再次感谢您的建议,但我们仍然没有抓住要点:) “减速”解决方案本质上就是“cpulimit”
再次感谢您的建议,但我们仍然没有抓住要点:) “减速”解决方案本质上就是“cpulimit”实用程序所做的。我仍然需要关注哪些进程需要减速,在工作进程完成后停止“减速”进程,并为新的工作进程启动新的进程。这正是我使用Perl脚本和cron作业所做的 主要的问题是,我事先不知道要限制哪些进程。它们是动态生成的 也许有一种方法可以将一个用户的所有进程限制在一定的CPU百分比范围内?我已经设置了一个用户来执行folding@home乔布斯,希望我能用/etc/security/limits.conf文件限制他。但我能得到的最接近的数据是每个用户的CPU总时间 如果能有一些东西让你说: “此用户进程的所有CPU%使用率之和不能超过50%”。然后让进程为其优先级争夺50%的CPU
伙计们,谢谢你们的建议,但这不是优先级的问题-我想限制CPU%即使有足够的CPU时间可用。这些流程的优先级已经很低,因此不会导致任何性能问题
我只想防止CPU长时间100%运行 我至少看到两种选择:
- 在创建进程的shell中使用“ulimit-t”
- 在流程创建时使用“nice”,或在运行时使用“renice”
loop
wait for some time tR
send SIGSTOP to the process you want to be scheduled
wait for some time tP
send SIGCONT to the process.
loopEnd
tR/tP比率控制cpu负载
这里有一点概念证明。“忙碌”是指占用cpu时间的程序,您希望通过“减速”来减速:
好的,这个脚本需要做更多的工作(例如,注意被插入,并让受控进程继续进行,以防它在那一刻停止),但是你明白了。我还将用C或类似语言编写这个小脚本,并从comand行参数计算cpu比率
关于在那里抛出一些睡眠调用会迫使进程在一定时间内离开CPU。如果您每分钟睡眠30秒一次,您的进程在这一分钟内的平均CPU使用率不应超过50%。我真的不明白您为什么要限制CPU时间。。。您应该限制该机器上的总负载,负载主要由IO操作决定。 例如:如果我创建一个while(1){}循环,它将使总负载达到1.0,但是如果这个循环进行一些磁盘写入,负载将跳到2.0。。。4.0. 这就是杀死你的机器的原因,而不是CPU的使用。nice/renice可以轻松处理CPU使用情况
无论如何,您可以创建一个脚本,当负载过高时为特定的PID执行“kill-SIGSTOP PID”,当一切恢复正常时执行kill-SIGCONT。。。PID可以通过使用'px aux'命令来确定,因为我看到它显示CPU使用情况,并且您应该能够使用该列对列表进行排序。我认为整个事情都可以在bash中完成…我有一个类似的问题,线程中提供的其他解决方案根本没有解决它。我的解决方案目前对我有效,但并不理想,尤其是对于进程由root所有的情况。
我现在的解决办法是尽力确保我没有root拥有的任何长时间运行的进程(比如备份只能作为用户完成) 我刚刚为gnome安装了硬件传感器小程序,并在CPU上设置高温和低温警报,然后为每个警报设置以下命令: 低: 高:
touch/tmp/hogs.txt&&ps-eopcpu,pid | sort-n-r | head-1 | gawk'{print$2}>/tmp/hogs.txt&&xargs-n1 kill-STOP
好消息是我的电脑不再过热和崩溃。缺点是终端进程在停止时会与终端断开连接,而在收到CONT信号时不会重新连接。另一件事是,如果它是一个导致过热的交互程序(就像某个Web浏览器插件),那么它会冻结在我正在做的事情的同时,等待CPU冷却。让CPU伸缩在全局级别上处理这个问题会更好,但问题是我的CPU上只有两个可选择的设置,而慢速设置的速度不足以防止过热
只是在这里重复一下,这与进程优先级、刷新无关,显然与停止长时间运行的作业无关。这与防止CPU利用率长时间停留在100%有关,因为硬件在满容量运行时无法足够快地散热(空闲CPU产生
> cat > busy.c:
main() { while (1) {}; }
> cc -o busy busy.c
> busy &
> top
Tasks: 192 total, 3 running, 189 sleeping, 0 stopped, 0 zombie
Cpu(s): 76.9% us, 6.6% sy, 0.0% ni, 11.9% id, 4.5% wa, 0.0% hi, 0.0% si
Mem: 6139696k total, 6114488k used, 25208k free, 115760k buffers
Swap: 9765368k total, 1606096k used, 8159272k free, 2620712k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26539 cg 25 0 2416 292 220 R 90.0 0.0 3:25.79 busy
...
> cat > slowDown
while true; do
kill -s SIGSTOP $1
sleep 0.1
kill -s SIGCONT $1
sleep 0.1
done
> chmod +x slowDown
> slowDown 26539 &
> top
Tasks: 200 total, 4 running, 192 sleeping, 4 stopped, 0 zombie
Cpu(s): 48.5% us, 19.4% sy, 0.0% ni, 20.2% id, 9.8% wa, 0.2% hi, 2.0% si
Mem: 6139696k total, 6115376k used, 24320k free, 96676k buffers
Swap: 9765368k total, 1606096k used, 8159272k free, 2639796k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26539 cg 16 0 2416 292 220 T 49.7 0.0 6:00.98 busy
...
mv /tmp/hogs.txt /tmp/hogs.txt.$$ && cat /tmp/hogs.txt.$$ | xargs -n1 kill -CONT
touch /tmp/hogs.txt && ps -eo pcpu,pid | sort -n -r | head -1 | gawk '{ print $2 }' >> /tmp/hogs.txt && xargs -n1 kill -STOP < /tmp/hogs.txt
gzip backup.tar & sleep 2 & cpulimit --limit 10 -e gzip -z
#!/bin/bash
# ==============================================================
# CPU limit daemon - set PID's max. percentage CPU consumptions
# ==============================================================
# Variables
CPU_LIMIT=20 # Maximum percentage CPU consumption by each PID
DAEMON_INTERVAL=3 # Daemon check interval in seconds
BLACK_PROCESSES_LIST= # Limit only processes defined in this variable. If variable is empty (default) all violating processes are limited.
WHITE_PROCESSES_LIST= # Limit all processes except processes defined in this variable. If variable is empty (default) all violating processes are limited.
# Check if one of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST is defined.
if [[ -n "$BLACK_PROCESSES_LIST" && -n "$WHITE_PROCESSES_LIST" ]] ; then # If both variables are defined then error is produced.
echo "At least one or both of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST must be empty."
exit 1
elif [[ -n "$BLACK_PROCESSES_LIST" ]] ; then # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
NEW_PIDS_COMMAND="top -b -n1 -c | grep -E '$BLACK_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
elif [[ -n "$WHITE_PROCESSES_LIST" ]] ; then # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6' | grep -E -v '$WHITE_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
else
NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6 && \$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
fi
# Search and limit violating PIDs
while sleep $DAEMON_INTERVAL
do
NEW_PIDS=$(eval "$NEW_PIDS_COMMAND") # Violating PIDs
LIMITED_PIDS=$(ps -eo args | gawk '$1=="cpulimit" {print $3}') # Already limited PIDs
QUEUE_PIDS=$(comm -23 <(echo "$NEW_PIDS" | sort -u) <(echo "$LIMITED_PIDS" | sort -u) | grep -v '^$') # PIDs in queue
for i in $QUEUE_PIDS
do
cpulimit -p $i -l $CPU_LIMIT -z & # Limit new violating processes
done
done
#!/bin/sh
#
# Script to start CPU limit daemon
#
set -e
case "$1" in
start)
if [ $(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print $1}' | wc -l) -eq 0 ]; then
nohup /usr/bin/cpulimit_daemon.sh >/dev/null 2>&1 &
ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon started successfully"; else print " * cpulimit daemon can not be started" }'
else
echo " * cpulimit daemon can't be started, because it is already running"
fi
;;
stop)
CPULIMIT_DAEMON=$(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print $1}' | wc -l)
CPULIMIT_INSTANCE=$(ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | wc -l)
CPULIMIT_ALL=$((CPULIMIT_DAEMON + CPULIMIT_INSTANCE))
if [ $CPULIMIT_ALL -gt 0 ]; then
if [ $CPULIMIT_DAEMON -gt 0 ]; then
ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print $1}' | xargs kill -9 # kill cpulimit daemon
fi
if [ $CPULIMIT_INSTANCE -gt 0 ]; then
ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | xargs kill -9 # release cpulimited process to normal priority
fi
ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon can not be stopped"; else print " * cpulimit daemon stopped successfully" }'
else
echo " * cpulimit daemon can't be stopped, because it is not running"
fi
;;
restart)
$0 stop
sleep 3
$0 start
;;
status)
ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh" {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon is running"; else print " * cpulimit daemon is not running" }'
;;
esac
exit 0
sudo chown root:root /etc/init.d/cpulimit
sudo chmod 755 /etc/init.d/cpulimit
sudo service cpulimit status
sudo service cpulimit start
sudo service cpulimit stop
sudo service cpulimit restart
#!/bin/bash
function lp
{
ps aux | grep $1 | termsql "select COL1 from tbl" > /tmp/tmpfile
while read line
do
TEST=`ps aux | grep "cpulimit -p $line" | wc -l`
[[ $TEST -eq "2" ]] && continue #cpulimit is already running on this process
cpulimit -p $line -l $2
done < /tmp/tmpfile
}
while true
do
lp gnome-terminal 5
lp system-journal 5
sleep 10
done
sudo systemd-run --scope --uid=1000 -p CPUQuota=20% my_heavy_computation.sh