将某些进程限制为CPU%-Linux

将某些进程限制为CPU%-Linux,linux,limit,cpu,Linux,Limit,Cpu,我有以下问题:一些动态生成的进程有消耗100%CPU的倾向。我想将所有符合某些标准(例如进程名)的进程限制在一定的CPU百分比范围内 我试图解决的具体问题是治理folding@home辅助进程。我能想到的最好的解决方案是一个perl脚本,它定期执行,并使用cpulimit实用程序来限制进程(如果您对更多细节感兴趣,请查看这个)。它是有效的,但它是一个黑客:/ 有什么想法吗?我想让操作系统来处理进程:) 再次感谢您的建议,但我们仍然没有抓住要点:) “减速”解决方案本质上就是“cpulimit”

我有以下问题:一些动态生成的进程有消耗100%CPU的倾向。我想将所有符合某些标准(例如进程名)的进程限制在一定的CPU百分比范围内

我试图解决的具体问题是治理folding@home辅助进程。我能想到的最好的解决方案是一个perl脚本,它定期执行,并使用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”

该命令可能会有所帮助。

您可以降低CPU频率。那么你就不必担心各个过程了。当您需要更多cpu时,请将频率放大。

PS+GREP+NICE

这可以使用setrlimit(2)(特别是通过设置RLIMIT\u cpu参数)来完成。

我不记得,也不认为unix调度程序中有类似的情况。您需要一个小程序来控制另一个进程,并执行以下操作:

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