web-dev-qa-db-ja.com

他のコマンドを実行するbashスクリプトのcpulimit

他のCPUを集中的に使用するコマンドを実行するbashスクリプトがあります。

Bashスクリプトにcpulimitを適用すると、topの出力は、スクリプト内のコマンドのプロセスがcpulimitによる制限なしに実行されていることを示しています。 bashスクリプト内のコマンドのCPU使用を制限するにはどうすればよいですか?

4
Tim

cpulimit --helpによると:

-i, --include-children limit also the children processes

私はこれが子供の子供に当てはまるかどうかをテストしておらず、これがどのように実装されているかについても調べていません。


または、カーネル機能であるcgroupsを使用することもできます。

Cgroupは、子プロセスを制限する手段もネイティブに提供しませんが、libcgroupが提供するcgルールエンジンデーモン(cgred)を使用できます。 libcgroupパッケージからのcgexecおよびcgclassifyコマンドは、ルールを子プロセスにも適用するための--stickyフラグを提供します。

could(少なくとも理論的には)一部の子プロセスが正しく制限されない結果となる競合状態が関係していることに注意してください。ただし、現在ユーザースペースで実行されるcpulimitを使用しているため、alreadyには100%信頼できるCPU制限がありません。この競合状態は、あなたにとって大きな問題になるべきではありません。

私はここでの自己回答でcgルールエンジンデーモンについてかなり広範囲に書いています:

2
Wildcard

今、私にとって最良の方法は、cpulimitがバックグラウンドでプロセスを制御できるようにするスクリプトを実行することでした Askubunt

#!/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.

スクリプトで使用されているプロセスを編集して、実行させます。 cpulimitはバックグラウンドで実行され、要求されたプロセスを監視し、その使用を制限します。プロセスのいずれかが終了した場合cpulimitは引き続き残り、プロセスが再び稼働した場合にプロセスを制限します。

(ターミナルのforループでffmpegを実行しようとすると、奇妙な問題が発生しました。これにより、逆説的に2つのffmpegインスタンスが生成され、cpulimitがほとんど役に立たなくなりました。 問題の答えが見つかりませんでした。 。 したがって、「単なるforループ」であっても、このためのスクリプトを作成する必要があるかもしれません。)

1
äxl

おそらく、できません。

cpulimitのロジックは非常に単純で、プロセスのpidを取り、そのシグナルをkill -STOP $PID、その後kill -CONT $PID、そして何度も何度も何度も何度も送信するだけです。 。

そして、CPU使用率を測定して、STOPとCONTの間の遅延を計算します。

あなたの場合、複雑なbashスクリプトのpstreeは、コンソールのN * x画面を使用します。

Bashスクリプトまたはバイナリ実行可能ファイルのCPU使用率をダウングレードする別の1つの方法を提案できます。

1)Nice-取得プロセスと、優先度を-20(最高の優先度)から20(最低の優先度)に増減します。おそらく低すぎるダイアパソンでは、それが理由で、別の2つのutilsとカーネルフックが表示されます。

2)ionice-Niceの第2世代である可能性があります。プロセスは、0(最低の優先度)から7(最高の優先度)までの優先度で分けることができます。 さらに、プロセスをクラス、リアルタイム(最高)、best-efforts(中)、アイドル(最低)、なし(デフォルト)で分けることができます。

3)chrt-私が今まで出会った中で最高のものであり、プロセスにおけるその力と支配性という点でcpulimitに似ています。ここでは、優先度のクラス、idlereal-timefifobatchなどを満たすこともできます...そして、優先度のダイアパソンは1から99。

たとえば、chrt -r -p 99 processを使用して1つの巨大なプロセスを起動すると、すべてのリソースが消費されます。

同様に、巨大なデーモンはchrt -r -p 0 processを使用して「バックグラウンド」でソフトに動作する可能性があります。システムのリソースがビジーの間、他のすべてのデーモンを待機します。

とにかく、始める前にman chrtman ioniceを読むことを強くお勧めします。

たとえば、p2pにrtorrentを使用しています。これは私のシステムにとって最も優先度の低いタスクであり、次のように起動します。

Nice -n 20 chrt -i 0 ionice -c3 /usr/bin/rtorrent

または、フック&ハックの方法を取ることができます。そして、独自の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
1
satosinakamoto