Killコマンドについて

プロセスを強制終了させる際に、 kill <PID> を使用したことはあると思います。 また、以前systemdについてまとめましたが、Unitファイル内でも kill コマンドの扱いを定義していました。

今回はこの kill コマンドについて、詳しく調べてみました。

killコマンドについて

説明

kill コマンドは、指定したシグナルを指定したプロセスまたはプロセスグループへ送る。 シグナルが指定されない場合、TERMシグナルを送る。 TERMシグナルは、このシグナルをキャッチしないプロセスを終了させる。 このシグナルをキャッチしてしまうプロセスを終了させるためには、 KILL (9) シグナルを使う必要がある。 最近のシェルのほとんどには、組み込みのkill機能があり、 ここで説明しているコマンドと同じような使い方をする。 -a' オプションと-p' オプション、 そしてコマンド名で PID を指定する方法はローカルな拡張である。

出典

つまり、kill コマンドはプロセスの強制終了のためではなく、プロセスへ何らかのシグナルを送るために用意されています。 そして、シグナルに TERM が使用された場合に、プロセスを強制終了させるます。

それでは、シグナルとはどういったもので、どのような種類があるのでしょうか。

シグナル

シグナルとは

「シグナル」はプロセスとプロセスの間で通信を行う際に使用される“信号”のことで、シグナルを受け取ったプロセスは“何らかの動作”を行います。その動作は、例えば「再起動」であったり、「終了」であったりします。

出典

コンソールでkill <PID>Ctrl+cCtrl+zと入力するとプロセスが終了しますが、これらもプロセスへ終了シグナルを送っていることになります。

シグナルの種類

シグナルの種類を一部、下記の通り紹介します。

先述の例で、Ctrl+c を上げましたが、これは下記のSIGINT を該当のプロセスへ送信していることになります。

シグナルの種類 シグナル番号 デフォルト動作 備考
SIGINT 2 終了 キーボードからの割り込み (Interrupt)
SIGTSTP 20 停止 端末より入力された一時停止 (stop)
SIGKILL 9 終了 Kill シグナル
SIGTERM 15 終了 終了 (termination) シグナル
SIGHUP 1 終了 制御端末(controlling terminal)のハングアップ検出、または制御しているプロセスの死
SIGQUIT 3 終了 キーボードによる中止 (Quit)、プロセスの終了とコアダンプ出力

出典

シグナル動作の種類

シグナルが送信されると、プロセスの通常処理に割り込んでシグナルが動作します。 シグナルの種類によりデフォルト動作は定義されており、以下の動作をそれぞれ実行します。

  1. プロセスを終了する
  2. コアを出力し、プロセスを終了する
  3. シグナルを無視する
  4. 処理を一時停止する
  5. 処理を再開する

出典

シグナル挙動の上書き

デフォルト動作は上記のように定義されていますが、シグナルを受け取った際に別の処理を実行させることもできます。 この別の処理は、プログラム側で実装します。

nginxの公式サイトにも、それぞれのシグナルを受け取った際にメインプロセスがどのような振る舞いをするかが記されています。

kill コマンドの使い方

書式

$ kill [-s signal | -p] [-a] [ --] pid ...
$ kill -l [signal]  

killのあとに、シグナル名もしくはシグナル番号を指定してPIDに対してコマンドを実行します。

まとめ

  • kill コマンドは、プロセスに対してシグナルを送信する。
  • シグナルには種類があり、それぞれ動作が異なる。
  • 各シグナルにはデフォルト動作があるか、その動作をプログラム側で書き換えることも可能。

補足

Unitファイル内で KillMode オプションを指定できます。 各値の動作は以下のようになっています。

systemdは起動したサービスに関連する全てのプロセスをCgroupの個別のグループに入れて管理している

ExecStopコマンドで停止した時、グループ内にプロセスが残っている場合、KillModeの設定に応じて残プロセス処理を行う

  • KillMode=none 残プロセスは放置
  • KillMode=process メインプロセスが残っている場合、SIGTERM/SIGKILLで停止する。その他の残プロセスは放置
  • KillMode=control-group グループ内の全ての残プロセスを SIGTERM/SIGKILL で停止する
  • KillMode=mixed メインプロセスを SIGTERM/SIGKILL で停止し、続けてグループ内の全ての残プロセスを SIGKILL で停止する。

出典