CPU負荷が最も高いプロセスを自動的にシャットダウンするには?

CPU負荷が最も高いプロセスを自動的にシャットダウンするには?

場合によっては、プログラムがバックグラウンドでロックされ、CPU使用率が高くなることがあります。現在最高のCPU負荷を引き起こすプロセスをプログラムで確認して終了する方法はありますか?

答え1

このタイプの作業に適していることを知っている場合は、より良いサービスを提供できる一連のUnixコマンドがあります。

  • 正規表現
  • 削除
  • それらすべてを殺す

特に、誤動作するプロセスの名前がわかっている場合は、これらのツールを使用して「攻撃」をさらにターゲットにすることができます。

それらすべてを殺す

Chromeを終了して最終的に解決する必要がある問題が引き続き発生します。私は通常それらをすべて殺すためにこのコマンドを使います。

$ killall chrome

pgrepとpkill

ただし、これを行うことも、最新のプロセスのみを処理することもできます。

# to list
$ pgrep -n chrome
23108

# to kill
$ pkill -n chrome

コマンドラインに基づいて殺す

-f実行可能ファイル名だけでなく、一致させたい長いパスパラメータを持つプロセスにアクセスするためにスイッチを追加することもできます。

たとえば、次のようなプロセスがあるとします。

$ ps -eaf | grep some
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  8 22:54 pts/44   00:00:00 some weird command's friend

彼らはただのBashシェルです。ARGV0次の名前に設定してください。ところで、私は次のプロセスにこのトリックを使用しました。

$ (exec -a "some weird command name's friend" bash)

友達を追う

しかし、これらの人がたくさんいて、コマンドラインに「友達」があるので、これらの中の特定のセットだけを追跡したいとしましょう。私はこれを行うことができます:

$ pgrep -f friend
26673
26911

最年少の友達を救う

いくつかあり、最新の項目を選択するには、-nスイッチをミックスに再度追加します。

$ pgrep -fn friend
26911

-fスイッチを登録するときに正規表現を使用することもできるので、次のように動作します。

$ pgrep -f "weird.*friend"
26673
26911

名前を見せて

スイッチを使用してプロセス名を再確認できます-l

$ pgrep -f "weird.*friend" -l
26673 some weird command's friend
26911 some weird command's friend

制御出力

または、pgrepカンマ(),で区切られたプロセスIDを一覧表示するように指示します。

$ pgrep -f "weird.*friend" -d,
26673,26911

次のような素晴らしい仕事をすることができます。

$ ps -fp $(pgrep -f weird -d,)
UID        PID  PPID  C STIME TTY          TIME CMD
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  0 22:54 pts/44   00:00:00 some weird command's friend

それでは、高いCPUプロセスを終了する方法は?

私は上記を使って高いCPUプロセスをより選択的に追求します。以下を使用して殺すことができます。

# newest guys
$ pkill -nf vlc ; pkill -nf opensnap

# kill all of these
$ killall vlc; killall opensnap

CPU負荷を見てください。

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | grep -v grep
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     
26673  0.1  112m 106m 6392  848 5020 1504    0    0 S  20   0  0.0 some weird command's friend 

ここで,区切り文字をコンマ()に変更しました。このスイッチは-d,パイプ(|)とも呼ばれます。このスイッチを-d\|使用すると、grep次のようにプロセスIDが返されます。

$ pgrep -f "weird.*friend" -d\|
26673|26911

grep -E ...次に、特定のプロセスIDに基づいて出力をフィルタリングできるようにコマンドに挿入します。top

これは大きな進歩のように見えるかもしれませんが、私たちが使用しているプロセスIDは「weird.*friend」という特定のプロセスに関連付けられているプロセスIDにすぎないことが確実にわかります。

ここでは、CPUが最高のプロセスを見つけて本当に欲しい場合は終了できます。

高いCPU処理に対するより目標化されたアプローチ

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | \
    grep -v grep | sort -nk14,14 | tail -1
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     

top上記の出力は、CPU列(列14)に基づいてソートされた出力です。最も低いものから高いものまでソートされるので、tail -1「weird.*friend」プロセスの中で最も高いCPUになる最後の行( )を選択します。

答え2

これを行うには、「and」プログラムAuto-Nice Daemonを設定できます。

いくつかの既知の問題要因のリストと3つの再処理レベル(ますます厳しく再処理できるように)を設定しましたが、そのうちの1つでもプロセスを終了できましたが、これは通常最後の手段として予約されています。

必要な特定のCPU負荷レベルを達成するために調整することは必ずしも簡単ではありませんが、役に立つ(そして攻撃を防ぎ、問題のあるプロセスを終了するのを防ぐのに役立ちます)cpulimitのようなNiceとioniceでプログラムを起動した他のツールがあります。

答え3

スクリプトの編集

@msw、@sim、および他のユーザーは私のスクリプトの概念について正当な懸念を提起しました。 @simの答えとmswの意見に触発され、いくつかの既知のプロセス(時々問題を引き起こすいくつかの既知のプロセス)を解決する方法をもう一度考えてみました。これが私が思いついたものです:

#!/bin/bash

# tries to kill process with highest CPU load
# (if it is part of a specified list of troublemakers)

TROUBLEMAKERS="vlc opensnap glxgears stress"


sleep 1 # wait a few seconds (just as a precaution)

TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')

if [[ "$TROUBLEMAKERS" == *"$TOPNAME"* ]]
  then
      echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
      echo "In troublemaker list. Killing..."
      kill -9 $TOPPID
  else
      echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
      echo "Not in troublemaker list. Exiting..."
      exit 1
fi

exit 0

以前のスクリプトとは異なり、このスクリプトは、名前が既知の多くの問題発生者(システムをロックしやすいプロセス)の1つと一致すると、CPU負荷が最も高いプロセスのみを終了します。


オリジナルスクリプト

以下は、システムで最高の瞬間CPU負荷を引き起こすプロセスを識別して終了する単純なスクリプトです(GUIを競合するXorgを除く)。

#!/bin/bash

# tries to kill process with highest CPU load
# (if it isn't Xorg)

sleep 1 # wait a few seconds (just as a precaution)

TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')

if [ "$TOPNAME" != "Xorg" ]
  then
      kill -9 $TOPPID
  else
      echo "CPU load caused by Xorg. Exiting."
      exit 1
fi

exit 0

このTOPPROCESSスニペットは以下に基づいています。このアイテムcommandlinefu.comから。

答え4

#!/bin/bash
pid=$(ps -eo %cpu,pid --sort -%cpu | head -n 2 | awk '{print $1 " " $2}')
if [[ -n $pid ]]; then
    kcpu=$(echo $pid | awk '{print $3}')
    kpid=$(echo $pid | awk '{print $4}')
    ift=$(echo "90"'<'$kcpu | bc -l)
    if [ $ift -eq "0" ]; then
        echo "kpid = $kpid"
        kill $kpid
    fi
else
echo "Does not exist"
fi

関連情報