しばらく寝るループは独自のPIDを取得します
-
10-10-2019 - |
質問
ループで並列処理を行うバッシュスクリプトがあります。並列プロセスがCPUをスパイクすることを望まないので、睡眠コマンドを使用します。これが簡素化されたバージョンです。
(while true;do sleep 99999;done)&
そこで、上記の行をバッシュプロンプトから実行して、次のようなものを取得します。[1] 12345
どこ [1]
ジョブ番号です 12345
whileループのプロセスID(PID)です。私はします kill 12345
取得:
[1]+ Terminated ( while true; do sleep 99999; done )
スクリプト全体が終了したようです。しかし、私はします ps aux|grep sleep
そして、睡眠コマンドがまだ強くなっているのを見つけますが、それ自体のPIDがあります!私は殺すことができます sleep
そして、すべてがうまくいくようです。しかし、もし私が最初に睡眠を殺すなら、whileループは新しいものを開始します sleep
pid。睡眠はwhileループと平行ではないので、これは私にとって非常に驚きです。ループ自体は、実行の単一のパスです。
だから私には2つの質問があります:
- スリープコマンドが独自のプロセスIDを取得したのはなぜですか?
- whileループと睡眠を簡単に殺すにはどうすればよいですか?
解決
- 睡眠は独自のものになります
PID
それは実行されているプロセスであり、ただ待っているからです。試すwhich sleep
それがどこにあるかを見るために。 - 使用できます
ps -uf
システム上のプロセスツリーを表示します。そこから、何を決定することができますPPID
睡眠のシェル(ループを実行しているもの)の(親pid)はです。
他のヒント
やってみましたか kill %1
, 、 どこ 1
コマンドをバックグラウンドで起動した後に得られる番号はありますか?
発売後、私は今それをしました (while true;do sleep 99999;done)&
そして、それはそれを正しく終了しました。
「PS -PPID」は、指定された親PIDですべてのプロセスを選択します。
$ (while true;do sleep 99999;done)&
[1] 12345
$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)
プロセスグループを殺すことができます。
プロセスのプロセスグループを見つけるには:
ps --no-headers -o "%r" -p 15864
次に、プロセスグループを殺します。
kill -- -[PGID]
すべてを1つのコマンドで行うことができます。試してみましょう:
$ (while true;do sleep 99999;done)&
[1] 16151
$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+ Terminated ( while true; do
sleep 99999;
done )
「睡眠」はプロセスであり、ビルドイン関数や同様のものではないため
次のことができます。
(while true;do sleep 99999;done)& whilepid=$! kill -- -$whilepid
上記のコードは、PIDが負の数(123ではなく-123など)として指定されているため、プロセスグループを殺します。さらに、変数を使用します $!
, 、最近実行されたプロセスのPIDを保存します。
注:インタラクティブモード(つまり、コマンドラインプロンプトを使用する)でバックグラウンドでプロセスを実行すると、新しいプロセスグループが作成されます。そうすれば、プロセスグループ全体を殺す必要があるため、「すべてを殺す」ことは比較的簡単です。ただし、スクリプト内で同じものが実行される場合、すべての新しいプロセスがバックグラウンドで実行されていても、すべての新しいプロセスがスクリプトPIDに属しているため、新しいグループを作成しません(ジョブコントロールはデフォルトで無効になります)。スクリプトでジョブコントロールを有効にするには、スクリプトの先頭に次のものを配置する必要があります。
#!/bin/bash
set -m
殺すために while
ループと sleep
使用 $!
aを使用することもできます trap
サブシェル内の信号ハンドラー。
(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}