32

次の問題があります。動的に生成された一部のプロセスは、CPU を 100% 消費する傾向があります。いくつかの基準 (プロセス名など) に一致するすべてのプロセスを特定の量の CPU パーセンテージに制限したいと考えています。

私が解決しようとしている特定の問題は、folding@home ワーカー プロセスを利用することです。私が考える最善の解決策は、定期的に実行され、cpulimit ユーティリティを使用してプロセスを制限する perl スクリプトです (詳細に興味がある場合は、このブログ投稿を確認してください)。動作しますが、ハックです:/

何か案は?プロセスの処理はOSに任せたいです:)


提案に感謝しますが、まだポイントがありません:)

「slowDown」ソリューションは、基本的に「cpulimit」ユーティリティが行うことです。どのプロセスを遅くするか、ワーカー プロセスが終了したら "slowDown" プロセスを強制終了し、新しいワーカー プロセスのために新しいプロセスを開始する必要があります。これは、まさに私が Perl スクリプトと cron ジョブで行ったことです。

主な問題は、どのプロセスを制限するかを事前に知らないことです。それらは動的に生成されます。

1 人のユーザーのすべてのプロセスを一定の CPU パーセンテージに制限する方法があるのではないでしょうか? /etc/security/limits.conf ファイルでユーザーを制限できることを期待して、folding@home ジョブを実行するユーザーを既にセットアップしました。しかし、私が得ることができる最も近いのは、ユーザーごとの合計 CPU 時間です...

「このユーザーのプロセスのすべての CPU 使用率 % の合計は 50% を超えることはできません」と言うことができる何かがあればクールです。そして、プロセスが優先順位に関してCPUの50%を争うようにします...


みんな、あなたの提案に感謝しますが、それは優先順位に関するものではありません.利用可能なCPU時間が十分にある場合でも、CPU%を制限したい. プロセスはすでに優先度が低いため、パフォーマンスの問題は発生しません。

CPUが長時間100%で実行されるのを防ぎたいだけです...

4

15 に答える 15

22

で少し似た問題がありましたgzip

gzipプロセスの CPU を減らしたいとします。

    gzip backup.tar & sleep 2 & cpulimit --limit 10 -e gzip -z

オプション:

  • 新しいプロセスをすぐに取得しない場合がsleepあるため、便利だと思いましたcpulimitgzip
  • --limit 10gzipCPU 使用率を 10% に制限します
  • -zプロセスが終了cpulimitすると自動的に閉じますgzip

もう 1 つのオプションは、cpulimitデーモンを実行することです。

于 2011-12-14T19:04:52.013 に答える
13

私は覚えていませんし、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 負荷を制御します。


ここに概念の小さな証明があります。「busy」は、CPU 時間を使い果たし、「slowDown」によって速度を落としたいプログラムです。

> 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
...

わかりました、そのスクリプトにはもう少し作業が必要です (たとえば、INTR-upted を処理し、その時点で停止された場合に制御されたプロセスを続行できるようにするなど)、要点はわかります。また、C などでその小さなスクリプトを記述し、コマンド ライン引数から CPU 比率を計算します。

よろしく

于 2008-12-22T21:19:43.030 に答える
8

Linuxには、CPU使用率を制限する解決策はないと思いますが、プロセスを特定のCPU使用率に制限する許容可能な方法があります:http://ubuntuforums.org/showthread.php?t = 992706

彼らが情報を削除した場合に備えて、ここに再びあります


  1. パッケージをインストールする

  2. cpulimitパッケージをインストールします。コード:

    sudo apt-get install cpulimit

  3. gawkパッケージをインストールします。コード:

    sudo apt-get install gawk

  4. CPULIMITデーモンファイルを作成する

root権限でテキストエディタを開き、次のデーモンスクリプトテキストを新しいファイル/usr/bin/cpulimit_daemon.shに保存します。

コード:

#!/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
  1. 環境ニーズに合わせて変数を変更します

CPU_LIMITすべてのプロセスのCPU消費を20%以外のパーセンテージに省略したい場合は、上記のスクリプトでこの変数を変更してください。SMPコンピュータ(1CPU以上または1コア以上のCPU)をお持ちの場合は、以下の「SMPコンピュータを使用する場合」の章をお読みください。

DAEMON_INTERVAL定期的なチェックを増やしたり減らしたりしたい場合は、上記のスクリプトでこの変数を変更してください。間隔は秒単位で、デフォルトは3秒に設定されています。

BLACK_PROCESS_LISTおよびWHITE_PROCESSES_LIST変数BLACK_PROCESSES_LISTは、指定されたプロセスのみを制限します。変数が空の場合(デフォルト)、違反しているすべてのプロセスが制限されます。

変数WHITE_PROCESSES_LISTは、この変数で定義されたプロセスを除くすべてのプロセスを制限します。変数が空の場合(デフォルト)、違反しているすべてのプロセスが制限されます。

変数BLACK_PROCESSES_LISTとWHITE_PROCESSES_LISTの一方または両方を空にする必要があります。両方の変数が定義されていることは論理的ではありません。

区切り文字「|」を使用して、この2つの変数のいずれかで複数のプロセスを指定できます。(二重引用符なし)。サンプル:mysql、firefox、geditプロセス以外のすべてのプロセスをcpulimitする場合は、変数を設定します:WHITE_PROCESSES_LIST = "mysql | firefox | gedit"

  1. 起動時にデーモンを自動的に起動する手順

  2. rootユーザーのファイル権限を設定します:コード:

    sudo chmod 755 /usr/bin/cpulimit_daemon.sh

  3. root権限でテキストエディタを開き、次のスクリプトを新しいファイル/etc/init.d/cpulimitに保存します

コード:

#!/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
  1. ファイルの所有者をルートに変更します。

コード:

sudo chown root:root /etc/init.d/cpulimit
  1. 権限の変更:

コード:

sudo chmod 755 /etc/init.d/cpulimit
  1. 起動手順ディレクトリにスクリプトを追加します。コード:

    sudoupdate-rc.dcpulimitのデフォルト

  2. 再起動して、スクリプトが起動時にcpulimitデーモンを起動するかどうかを確認します。コード:

    sudoリブート

  3. デーモンを手動で確認、停止、開始、および再起動します

注:このチュートリアルのデーモンとサービスは同じ意味です。

注:サービスコマンドの代わりにUbuntu 8.10より前(Ubuntu 8.04 LTSなど)を使用しているユーザーの場合は、「sudo /etc/init.d/cpulimit status / start / stop / restart」構文を使用するか、コマンドsudoapt-getを使用してsysvconfigパッケージをインストールします。 sysvconfigをインストールします

cpulimitサービスが実行されているかどうかを確認します。Checkコマンドは、サービスが実行されている場合は「cpulimitデーモンが実行されています」、サービスが実行されていない場合は「cpulimitデーモンが実行されていません」を返します。コード:

sudo service cpulimit status

cpulimitサービスの開始CPU消費を省略し始めるcpulimitデーモンを手動で開始できます。コード:

sudo service cpulimit start

Stop cpulimit service Stopコマンドは、cpulimitデーモンを停止し(したがって、新しいプロセスが制限されることはありません)、cpulimitが実行されていない前と同じように、既存のすべての制限されたプロセスがCPUに完全にアクセスできるように設定します。コード:

sudo service cpulimit stop

cpulimitサービスを再起動する/usr/bin/cpulimit_daemon.shのCPU_LIMIT、DAEMON_INTERVAL、BLACK_PROCESSES_LIST、WHITE_PROCESSES_LISTなどの変数設定を変更した場合は、設定を変更した後、サービスを再起動する必要があります。コード:

sudo service cpulimit restart
  1. CPU制限デーモンがある場合とない場合のCPU消費量を確認します

デーモンなし1.cpulimitデーモンを停止します(sudo service cpulimit stop)2.バックグラウンドでCPU集中型タスクを実行します3.コマンドを実行します:topおよび%CPU列を確認します%CPUの結果はおそらく各プロセスで20%以上です。

デーモンをオンにした状態1.cpulimitデーモンを開始します(sudo service cpulimit start)2.バックグラウンドで同じCPU集中タスクを実行します3.コマンドを実行します:topおよび%CPU列を確認します%CPUの結果は各プロセスで最大20%である必要があります。注:デーモンは3秒間隔で違反プロセスをキャッチする必要があるため、最初は%CPUが20%を超える可能性があることを忘れないでください(デフォルトではスクリプトで設定されています)

  1. SMPコンピューターを使用する場合

このコードをIntelデュアルコアCPUコンピューターでテストしました。これはSMPコンピューターのように動作します。topコマンドとcpulimitは、デフォルトでIrixモードで動作することを忘れないでください。20%は1つのCPUの20%を意味します。2つのCPU(またはデュアルコア)がある場合、合計%CPUは200%になる可能性があります。topコマンドでは、コマンドI(topコマンドの実行中に+ iを押す)でIrixモードをオフにし、Solarisモードをオンにすることができます。このモードでは、CPUの合計量をCPUの数で割ったため、%CPUは100を超えることはできません。任意の数のCPUコンピューターで%。トップマンページでトップコマンドの詳細をお読みください(Iコマンドを検索してください)。cpulimitの公式ページで、cpulimitがSMPコンピューターでどのように動作しているかについてもお読みください。

しかし、cpulimitデーモンはSMPコンピューターでどのように動作しますか?常にIrixモードです。したがって、CPUパワーの20%を2 CPUコンピューターに費やしたい場合は、cpulimitデーモンスクリプトのCPU_LIMIT変数に40%を使用する必要があります。

  1. CPULIMITデーモンとCPULIMITプログラムをアンインストールします

cpulimitデーモンを削除したい場合は、cpulimitデーモンを削除してcpulimitプログラムをアンインストールすることにより、システムをクリーンアップできます。

  1. cpulimitデーモンを停止しますコード:

    sudo service cpulimit stop#cpulimitデーモンとすべてのcpulimitedプロセスを停止します

  2. 起動手順からデーモンを削除しますコード:

    sudo update-rc.d -f cpulimit remove#シンボリックリンクを削除します

  3. 起動手順の削除コード:

    sudo rm /etc/init.d/cpulimit#cpulimitブートアップスクリプトを削除します

  4. cpulimitデーモンコードを削除します。

    sudo rm /usr/bin/cpulimit_daemon.sh#cpulimitデーモンスクリプトを削除します

  5. cpulimitプログラムのアンインストールコード:

    sudo apt-get remove cpulimit

  6. gawkプログラムのアンインストール他のスクリプトでこのプログラムが必要ない場合は、リモートで実行できます。コード:

    sudo apt-get remove gawk

  7. 著者についての注意

cpulimit用のデーモン(上記のbashスクリプト)を作成しました。私はcpulimitプロジェクトの作者ではありません。cpulimitプログラムの詳細については、cpulimitの公式Webページ(http://cpulimit.sourceforge.net/ )を参照してください。

よろしく、Abcuser

于 2012-04-17T02:16:09.043 に答える
4

cgroups のcpu.sharesを使用しても、 nice値でできないことは何もありません。プロセスを実際に調整したいようですが、これは間違いなく実行できます。

必要なパラメータを定義するには、 1 つまたは 2 つのスクリプトを使用するか、/etc/ cgconfig.confを編集する必要があります。

具体的には、値cpu.cfs_period_usおよびcpu.cfs_quota_usを編集します。プロセスは、cpu.cfs_period_usマイクロ秒ごとにcpu.cfs_quota_usマイクロ秒実行できます。

例えば:

cpu.cfs_period_us = 50000およびcpu.cfs_quota_us = 10000の場合、他に何が起こっていても、プロセスは最大 CPU 時間の 20% を受け取ります。

このスクリーンショットでは、プロセスに CPU 時間の 2% を与えています。

2% の CPU 時間

プロセスに関する限り、100% で実行されています。

一方、cpu.sharesを設定すると、アイドル状態の CPU 時間を 100% 使用できます。

この同様の例では、プロセスcpu.shares = 100 (of 1024)を指定しました。

cpu.shares

ご覧のとおり、プロセスはまだすべてのアイドル状態の CPU 時間を消費しています。

参考文献:

http://manpages.ubuntu.com/manpages/precise/man5/cgconfig.conf.5.html http://kennystechtalk.blogspot.co.uk/2015/04/throttling-cpu-usage-with-linux-cgroups .html

于 2015-04-10T04:37:14.427 に答える
4

私は同様の問題を抱えていましたが、スレッドに示されている他の解決策はまったく解決していません。私の解決策は今のところうまくいきますが、特にプロセスがルートによって所有されている場合は、最適ではありません。
現時点での私の回避策は、ルートが所有する実行時間の長いプロセスがないことを確認するために非常に努力することです (バックアップをユーザーとしてのみ実行するなど)。

gnome 用のハードウェア センサー アプレットをインストールし、CPU の高温と低温のアラームを設定し、アラームごとに次のコマンドを設定しました。

低い:

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

幸いなことに、コンピューターがオーバーヒートしたりクラッシュしたりすることはなくなりました。欠点は、端末プロセスが停止すると端末から切断され、CONT シグナルを受信して​​も再接続されないことです。もう 1 つのことは、オーバーヒートの原因となった対話型プログラム (特定の Web ブラウザー プラグインなど) である場合、CPU が冷えるのを待っている間、作業の途中でフリーズすることです。CPU スケーリングがこれをグローバル レベルで処理する方がよいでしょうが、問題は、CPU で選択可能な設定が 2 つしかないことと、低速設定では過熱を防ぐのに十分な速度ではないことです。

ここで繰り返しますが、これはプロセスの優先順位や再ナイシングとはまったく関係がなく、明らかに長時間実行されるジョブの停止とは関係ありません。これは、CPU 使用率が長時間 100% にとどまるのを防ぐことに関係しています。これは、ハードウェアがフル キャパシティで動作しているときに熱を十分にすばやく放散できないためです (アイドル状態の CPU は、完全にロードされた CPU よりも熱を生成しません)。

役立つ可能性のある他のいくつかの明白な可能性は次のとおりです。

BIOS で全体的な CPU 速度を下げる

ヒートシンクを交換するか、サーマル ジェルを再塗布して、問題が解決するかどうかを確認します。

圧縮空気でヒートシンクを掃除する

CPUファンを交換する

[編集] 注: BIOS (asus p5q pro turbo) で可変ファン速度を無効にすると、CPU が 100% で過熱することはもうありません。CPU が完全にロードされると、各コアは摂氏 49 度で最高になります。

于 2010-09-19T04:33:14.877 に答える
0

少なくとも 2 つのオプションがあります。

  • プロセスを作成するシェルで「ulimit -t」を使用します
  • プロセスの作成時に「nice」を使用するか、実行時に「renice」を使用します
于 2008-12-22T18:29:45.353 に答える
0

PS + GREP + ナイス

于 2008-12-22T20:51:57.750 に答える
-1

そこにいくつかのスリープ呼び出しをスローすると、プロセスが一定時間CPUから強制的にオフになります。1分間に30秒間スリープする場合、プロセスはその1分間の平均CPU使用率が50%を超えないようにする必要があります。

于 2008-12-22T21:47:08.870 に答える
-1

niceコマンドがおそらく役に立ちます。

于 2008-12-22T18:32:02.820 に答える
-1

これは setrlimit(2) を使用して行うことができます (具体的には RLIMIT_CPU パラメータを設定することにより)。

于 2008-12-22T20:53:22.240 に答える
-2

CPU 周波数を下げることができます。その後、個々のプロセスについて心配する必要はありません。より多くの CPU が必要な場合は、周波数を元に戻してください。

于 2008-12-22T20:48:18.927 に答える