我有一个 bash 脚本,它运行其他 cpu 密集型命令。
当我应用于cpulimit
bash 脚本时,top
显示脚本内命令的进程的输出仍然运行,不受cpulimit
.我想知道如何限制 bash 脚本中命令的 cpu 使用率?
答案1
根据cpulimit --help
:
-i, --include-children limit also the children processes
我没有测试这是否适用于儿童的孩子,也没有研究这是如何实施的。
或者,您可以使用cgroups
,这是一个内核功能。
Cgroup 本身并不提供限制子进程的方法,但您可以使用 libcgroup 提供的 cg 规则引擎守护进程 (cgred);来自 libcgroup 包的cgexec
和命令提供了一个标志,使规则也适用于子进程。cgclassify
--sticky
请注意,其中涉及竞争条件可以(至少理论上)导致某些子进程没有被正确限制。但是,由于您当前正在使用cpulimit
在用户空间中运行的命令,因此您已经没有 100% 可靠的 CPU 限制,因此这种竞争条件不应成为您的交易障碍。
我在此处的自我回答中详细介绍了 cg 规则引擎守护进程:
答案2
也许,你不能。
cpulimit
逻辑很简单,它需要进程的 pid 并简单地发送其信号kill -STOP $PID
,然后kill -CONT $PID
,再一次,再一次,再一次,再一次......
并测量 cpu 使用率来计算 STOP 和 CONT 之间的延迟。
在您的情况下,pstree
复杂的 bash 脚本将占用控制台的 N*x 屏幕。
我可以向您建议另一种方法来降低任何 bash 脚本甚至二进制可执行文件的 cpu 使用率。
1) nice
- 其获取过程并将其优先级从-20(最高优先级)增加或减少到20(最低优先级)。可能音调太低,这就是为什么,出现了另外两个 utils 和内核钩子:
2) ionice
- 可能是第二代nice
.您可以按优先级从 0(最低优先级)到 7(最高优先级)分隔进程。另外,您可以按类别、实时(最高)、best-efforts
(中间)、空闲(最低)和无(默认)来分隔进程。
3) chrt
- 我所见过的最高的事物,它类似于cpulimit
它的力量和对过程的统治。在这里您也可以遇到优先级类别,idle
,real-time
,fifo
,batch
,等等...并且优先级范围非常大,从1到99。
例如,您可以启动一个巨大的进程chrt -r -p 99 process
- 它会耗尽您的所有资源。
同样,任何大型守护进程都可以在“后台”进行软运行chrt -r -p 0 process
- 当系统资源繁忙时,它将等待其他进程。
不管怎样,我强烈建议你在开始之前阅读man chrt
一下。man ionice
例如,我用于rtorrent
p2p。它是我的系统的最低优先级任务,然后我以这样的方式启动它:
nice -n 20 chrt -i 0 ionice -c3 /usr/bin/rtorrent
或者,您可以采取 hooks&haks 方式。并编写您自己的 cpulimit_wrapper 脚本。例如:
# cat bash_script.sh
#!/bin/bash
while sleep 0; do
find /
dd if=/dev/random of=/tmp/random.bin bs=1M count=1000
done
加
# cat cpulimit.sh
#!/bin/bash
TARGET=$1
[ -z "$TARGET" ] && echo "Usage bash cpulimit.sh command" && exit 1
cpulimit -l 1 bash $TARGET
while sleep 0;do
lsof -n -t $TARGET | xargs pstree -p | sed -e 's/(/(\n/g' | sed -e 's/)/\n)/g' | egrep -v '\(|\)' | while read i; do
echo $i;
cpulimit -l 1 -b -p $i;
done
done
答案3
现在对我来说最好的方法是运行一个脚本,让CPU限制后台控制进程阿斯库本图:
#!/bin/bash
#The first variable is to set the number of cores in your processor. The reason that the number of cores is important is that you need to take it into consideration when setting cpulimit's -l option. This is explained on the cpulimit project page (see http://cpulimit.sourceforge.net/): "If your machine has one processor you can limit the percentage from 0% to 100%, which means that if you set for example 50%, your process cannot use more than 500 ms of cpu time for each second. But if your machine has four processors, percentage may vary from 0% to 400%, so setting the limit to 200% means to use no more than half of the available power."
NUM_CPU_CORES=$(nproc --all) #Automatically detects your system's number of CPU cores.
cpulimit -e "ffmpeg" -l $((50 * $NUM_CPU_CORES))& #Limit "ffmpeg" process to 50% CPU usage.
cpulimit -e "zero-k" -l $((50 * $NUM_CPU_CORES))& #Limit "zero-k" process to 50% CPU usage.
cpulimit -e "mlnet" -l $((50 * $NUM_CPU_CORES))& #Limit "mlnet" process to 50% CPU usage.
cpulimit -e "transmission-gtk" -l $((50 * $NUM_CPU_CORES))& #Limit "transmission-gtk" process to 50% CPU usage.
cpulimit -e "chrome" -l $((40 * $NUM_CPU_CORES))& #Limit "chrome" process to 40% CPU usage.
编辑脚本中使用的进程并让它运行。CPU限制将在后台运行并监视询问的进程并限制其使用。如果任何一个进程完成CPU限制如果它们再次活跃起来,仍然会留下来并限制进程。
(我遇到了一个奇怪的问题,我试图通过终端中的 for 循环运行 ffmpeg。这矛盾地产生了两个 ffmpeg 实例,这使得 cpulimit'ing 几乎毫无用处。我找不到问题的答案。因此,即使它“只是一个 for 循环”,您也可能需要为此编写一个脚本。)
答案4
cpulimit -l 50 ffmpeg
我尝试为in设置别名.bashrc
alias ffmpegl = "cpulimit -l 50 ffmpeg"
然后在我的脚本中使用它并使用以下代码来获取别名
shopt -s expand_aliases
source /home/your_user/.bashrc
现在我可以在脚本内的任何位置使用 cpulimit 和 ffmpeg 使用别名来执行多个命令。在 Scientific Linux 6.5 上测试。完美运行。