シグナル

プロセス間の非同期通知

シグナルとは

シグナルは、プロセスに非同期に通知を送る仕組みです。 プロセスの終了要求、一時停止、再開、設定再読み込みなどに使用されます。 カーネルやユーザー、他のプロセスから送信できます。

主要なシグナル

番号名前説明デフォルト動作
1SIGHUP端末切断、設定再読み込み終了
2SIGINT割り込み(Ctrl+C)終了
3SIGQUITコアダンプ付き終了(Ctrl+\)コアダンプ+終了
9SIGKILL強制終了(捕捉不可)終了
15SIGTERM終了要求(デフォルト)終了
18SIGCONT再開再開
19SIGSTOP停止(捕捉不可)停止
20SIGTSTP一時停止(Ctrl+Z)停止
10/12SIGUSR1/2ユーザー定義終了

SIGTERM vs SIGKILL

SIGTERM (15)

  • • 「終了してください」のお願い
  • 捕捉可能
  • • クリーンアップ処理が可能
  • • graceful shutdown
  • • kill のデフォルト

SIGKILL (9)

  • • 「今すぐ死ね」の強制
  • 捕捉不可
  • • クリーンアップなし
  • • データ損失の可能性
  • • 最後の手段として使用

ベストプラクティス: まずSIGTERM → 数秒待機 → 応答なければSIGKILL

シグナルの送信

1# kill コマンド
2kill <PID> # SIGTERM(デフォルト)
3kill -15 <PID> # SIGTERM(明示)
4kill -9 <PID> # SIGKILL
5kill -HUP <PID> # SIGHUP(設定再読み込み)
6
7# シグナル名で指定
8kill -s SIGTERM <PID>
9
10# 全シグナル一覧
11kill -l
12
13# プロセス名で送信
14pkill nginx # 名前でSIGTERM
15pkill -9 nginx # 名前でSIGKILL
16killall nginx # 全マッチにSIGTERM
17
18# プロセスグループに送信
19kill -TERM -<PGID>
20
21# Ctrl+C, Ctrl+Z
22# Ctrl+C → SIGINT
23# Ctrl+Z → SIGTSTP
24# Ctrl+\ → SIGQUIT

シグナルハンドリング

プロセスはシグナルに対して3つの対応が可能です(SIGKILL/SIGSTOP除く):

デフォルト動作

カーネル定義の動作を実行

捕捉(ハンドラ)

独自の処理を実行

無視

シグナルを無視

1# Bashでのシグナルハンドリング
2trap 'echo "SIGINT received"; exit 1' SIGINT
3trap 'echo "cleaning up..."; rm -f /tmp/lockfile' EXIT
4
5# シグナル無視
6trap '' SIGINT # Ctrl+C を無視
7
8# デフォルトに戻す
9trap - SIGINT

シグナルの実用例

SIGHUP: 設定再読み込み

kill -HUP nginx でnginxの設定をリロード

SIGUSR1: ログローテート

kill -USR1 nginx でログファイル再オープン

SIGTERM: graceful shutdown

処理中のリクエストを完了してから終了

SRE/インフラ観点

Kubernetes との関連

  • • Pod終了時: SIGTERM → terminationGracePeriod → SIGKILL
  • • preStop hookでクリーンアップ処理
  • • アプリケーションはSIGTERMを適切に処理すべき

トラブルシューティング

  • • SIGKILLでも終了しない → D状態(I/O待ち)の可能性
  • • シグナル無視設定の確認: cat /proc/PID/status | grep Sig