1. 概要

Linuxシステム管理の一般的なシナリオは、プロセス管理です。 ほとんどのプロセスは簡単に停止および管理できますが、同じグループ内の多数のプロセスを停止する必要があるシナリオもあります。

このチュートリアルでは、プロセスグループを使用したプロセス管理について説明します。 また、プロセスグループに属するすべてのプロセスを強制終了する方法。

2. プロセスグループ

Linuxのプロセスグループは、その名前が示すように、Linuxグループが一緒に処理する方法です。 これらは、同じPGID(プロセスグループID)を共有する関連プロセスのコレクションです。

よくある誤解は、親プロセスを強制終了すると子プロセスも強制終了するというものです。 それでも、親プロセスを強制終了すると、子プロセスが単独で存在できるようになる可能性があります。 プロセスグループIDを使用してプロセスを強制終了すると、関連するすべてのプロセスが確実に停止することがわかります。

各プロセスグループには、プロセスIDがグループ内のすべてのプロセスのPGIDと同じであるグループリーダーがあります

3. グループ化されたプロセスのリストの設定

実行中のアプリケーションプロセスの階層があるシナリオを想定しています。 したがって、相互に呼び出す3つのスクリプトを作成し、同じグループに属する一連のプロセスを作成します。

先に進んで、grandparent.shという名前のシェルスクリプトを以下の内容で作成しましょう。

#!/bin/bash
bash parent.sh &
bash parent.sh &
for i in {1..100}; do 
sleep 2; 
echo -n "This is the grandparent process $i"; 
done

同様に、parent.shおよびchildren.shという名前のスクリプトをさらに2つ作成しましょう。

#!/bin/bash
bash children.sh &
bash children.sh &
for i in {1..100}; do sleep 2; echo -n "This is the parent process $i"; 
done
#!/bin/bash
for i in {1..100}; do 
sleep 2; 
echo -n "This is a test in children process $i"; 
done

次に、最上位のスクリプトを実行して、以下のコマンドを使用して他のプロセスを作成します。

./grandparent.sh

4. psコマンドを使用してプロセスグループを検索する

ps コマンドを使用して、以下のオプションでアクティブなプロセスのリストを取得します。

  • -e :すべてのプロセスを選択します
  • -f :フルフォーマットのリストを作成するために、PGIDと追加の列はデフォルトではpsコマンドで使用できません。
  • -j :プロセスをジョブ形式で一覧表示します。
$ ps -efj
UID          PID    PPID    PGID     SID  C STIME TTY          TIME CMD
root           1       0       1       1  0 11:18 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 18
root           2       0       0       0  0 11:18 ?        00:00:00 [kthreadd]
root           3       2       0       0  0 11:18 ?        00:00:00 [rcu_gp]
root           4       2       0       0  0 11:18 ?        00:00:00 [rcu_par_gp]
root           6       2       0       0  0 11:18 ?        00:00:00 [kworker/0:0H]
root           8       2       0       0  0 11:18 ?        00:00:00 [mm_percpu_wq]
root           9       2       0       0  0 11:18 ?        00:00:00 [ksoftirqd/0]
root          10       2       0       0  0 11:18 ?        00:00:00 [rcu_sched]

5. プロセスリスト出力のフィルタリング

システムで実行されているプロセスの数に応じて、出力をフィルタリングする必要があります。 いくつかのツールを使用して、停止しようとしているプロセスのProcessGroudIdを見つけましょう。

セクション3の設定から、同じPGIDを共有するプロセスのグループが必要です。

$ ps -efj | egrep "PGID|children|parent"

UID          PID    PPID    PGID     SID  C STIME TTY          TIME CMD
vagrant     6389    5377    6389    5377  0 12:49 pts/0    00:00:00 bash grandparent.sh
vagrant     6390    6389    6389    5377  0 12:49 pts/0    00:00:00 bash parent.sh
vagrant     6391    6389    6389    5377  0 12:49 pts/0    00:00:00 bash parent.sh
vagrant     6393    6390    6389    5377  0 12:49 pts/0    00:00:00 bash children.sh
vagrant     6394    6390    6389    5377  0 12:49 pts/0    00:00:00 bash children.sh
vagrant     6395    6391    6389    5377  0 12:49 pts/0    00:00:00 bash children.sh
vagrant     6397    6391    6389    5377  0 12:49 pts/0    00:00:00 bash children.sh
vagrant     6440    4570    6439    4570  0 12:49 pts/1    00:00:00 grep -E --color=auto PGID|children|parent

セクション2で説明したように、他のすべてのプロセスを開始する最初のプロセスのPIDは、他のすべてのプロセスのPGIDとして使用されます。

6. PGIDを使用してプロセスを強制終了する

kill コマンドを使用して、以下の形式を使用して、指定されたプロセスグループにkillシグナルを送信してみましょう。

kill -- -$PGID

二重ダッシュ「–」は、デフォルトのSIGTERM信号用です。 セクション5に見られるように、私たちが殺そうとしているプロセスのグループのPGIDは6389です。 これを知っていると、killコマンドでこのグループを強制終了できます。

kill -- -6389

プロセスで通常使用する任意の信号を使用することもできます。 たとえば、 SIGKILL -9 を使用して、プロセスグループを強制終了します。

kill -9 -6389

さらに、 SIGQUIT 信号をプロセスグループに送信して、ターミナル終了信号を複製することができます。

kill -SIGQUIT -6389

7. 結論

この記事では、 kill コマンドを使用して、同じプロセスグループに属するプロセスを終了する方法を説明しました。 SIGTERMまたはSIGQUITシグナルのいずれかを送信することで終了できます。 このアプローチを使用してプロセスを強制終了すると、多数のプロセスが継続的に開始されるシナリオで役立ちます。 プログラムと関連するすべてのプロセスを停止する必要があります。