Linux – シグナルについて

目次

概要

本記事では、Linux のプロセス間通信の一形態であるシグナルについて説明します。kill、pkill、killall コマンドでプロセスに対してシグナルを送信する方法について解説します。

シグナル

シグナルは、プロセス間通信 (Inter-Process Communication, IPC) の一形態で、特定のイベントが発生したことをプロセスに通知するために使用されます。シグナルは、プロセスに対して非同期に送信される短いメッセージであり、プロセスが特定のアクションを実行するためのトリガーとなります。

シグナルは整数値で識別され、各シグナルには特定の意味が割り当てられています。例えば、SIGINT はキーボードの割り込み (Ctrl+C) を示し、SIGTERM はプロセスの終了要求を示します。シグナルの詳細なリストは kill -l コマンドで確認できます。

シグナルの種類

シグナルの一覧

以下にシグナルの一覧をテーブル形式で示します:

シグナル名 番号 説明 デフォルト動作
SIGHUP 1 ハングアップ (端末の切断) 終了と再読み込み
SIGINT 2 割り込み (Ctrl+C) 終了
SIGQUIT 3 終了 (Ctrl+\) コアダンプと終了
SIGILL 4 不正命令 コアダンプと終了
SIGTRAP 5 トレース/ブレークポイントトラップ コアダンプと終了
SIGABRT 6 プロセス中断 コアダンプと終了
SIGBUS 7 バスエラー コアダンプと終了
SIGFPE 8 浮動小数点例外 コアダンプと終了
SIGKILL 9 強制終了 (キャッチ不可) 終了
SIGUSR1 10 ユーザー定義シグナル 1 終了
SIGSEGV 11 セグメンテーション違反 コアダンプと終了
SIGUSR2 12 ユーザー定義シグナル 2 終了
SIGPIPE 13 パイプ破損: 書き込み側のプロセスなし 終了
SIGALRM 14 タイマーシグナル 終了
SIGTERM 15 終了要求 終了
SIGSTKFLT 16 スタックフォルト 終了
SIGCHLD 17 子プロセスの状態変化 無視
SIGCONT 18 停止していたプロセスの継続 継続
SIGSTOP 19 プロセスの停止 (キャッチ不可) 停止
SIGTSTP 20 端末からの停止 (Ctrl+Z) 停止
SIGTTIN 21 バックグラウンドプロセスの tty 入力 停止
SIGTTOU 22 バックグラウンドプロセスの tty 出力 停止
SIGURG 23 緊急データの到着 (ソケット) 無視
SIGXCPU 24 CPU 時間制限を超過 終了
SIGXFSZ 25 ファイルサイズ制限を超過 終了
SIGVTALRM 26 仮想タイマーシグナル 終了
SIGPROF 27 プロファイリングタイマーシグナル 終了
SIGWINCH 28 ウィンドウサイズの変更 無視
SIGIO 29 I/O 可能 終了
SIGPOLL 29 ポーリングイベント (SIGIO と同じ) 終了
SIGPWR 30 電源障害 終了
SIGSYS 31 不正なシステムコール コアダンプと終了
SIGRTMIN ~ SIGRTMAX 34~64 リアルタイムシグナル 終了

ユーザー定義シグナル

ユーザー定義シグナルは、ユーザーが自由に定義してプログラムやスクリプトが自由に使用できるシグナルです。

シグナル名 番号 説明 デフォルト動作
SIGUSR1 10 ユーザー定義シグナル 1 終了
SIGUSR2 12 ユーザー定義シグナル 2 終了
SIGRTMIN ~ SIGRTMAX 34~64 リアルタイムシグナル 終了

シグナルの送信

シグナルは kill コマンド、pkill コマンド、killall コマンドを使用して、プロセスに送信できます。

kill コマンド

kill -TERM <pid>

kill コマンドの基本的な使用方法は以下の通りです。 シグナルの種類は、シグナル名または番号で指定します。 シグナルを指定しない場合、デフォルトで SIGTERM が使用されます。

# プロセスID 1234 に SIGTERM シグナルを送信
kill 1234

# プロセスID 1234 に SIGKILL シグナルを送信
kill -9 1234

# プロセスID 1234 に SIGUSR1 シグナルを送信
kill -USR1 1234

pkill コマンド

pkill コマンドは、プロセス名やその他の属性でプロセスを検索し、条件に一致するプロセス全てにシグナルを送信するためのコマンドです。
シグナルを指定しない場合、デフォルトで SIGTERM が使用されます。

# "myprocess" という名前のプロセスに SIGTERM シグナルを送信
pkill myprocess

# "myprocess" という名前のプロセスに SIGKILL シグナルを送信
pkill -KILL myprocess

# ユーザー名が "user1" のプロセスに SIGUSR1 シグナルを送信
pkill -USR1 -u user1

killall コマンド

killall コマンドは、指定された名前と一致するすべてのプロセスに対してシグナルを送信するためのコマンドです。
プロセス名は完全一致で判定され、シグナルを指定しない場合は SIGTERM が使用されます。

# "myprocess" という名前のすべてのプロセスに SIGTERM シグナルを送信
killall myprocess

# "myprocess" という名前のすべてのプロセスに SIGKILL シグナルを送信
killall -9 myprocess

# "myprocess" という名前のすべてのプロセスに SIGUSR2 シグナルを送信
killall -s SIGUSR2 myprocess

シグナルのハンドリング

プロセスはシグナルを受け取ったときに特定のアクションを実行するように設定できます。 signal() 関数を使用して、シグナルとそのシグナルを受け取ったときのコールバック関数を登録します。

シグナルを処理する

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handle_signal(int signal) {
    if (signal == SIGUSR1) {
        printf("Received SIGUSR1\n");
    }
}

int main() {
    // SIGUSR1 シグナルを受信したときのハンドラを設定
    signal(SIGUSR1, handle_signal);

    // 無限ループでシグナルを待つ
    while (1) {
        printf("Waiting for SIGUSR1...\n");
        sleep(1);
    }

    return 0;
}

このプログラムは、SIGUSR1 シグナルを受け取ると “Received SIGUSR1” と表示します。

シグナルを無視する

特定のシグナルを無視するように設定することもできます。これには SIG_IGN 定数を使用します。

#include <signal.h>
#include <unistd.h>

int main() {
    // SIGHUP シグナルを無視
    signal(SIGHUP, SIG_IGN);

    // 無限ループでシグナルを待つ
    while (1) {
        sleep(1);
    }

    return 0;
}

シグナルを受け取らない場合

シグナルを受け取らない、つまりシグナルハンドラが設定されていない場合、各シグナルにはデフォルトの動作があり、そのデフォルト動作が実行されます。シグナルのデフォルト動作は、シグナルの種類によって異なります。

コメント

コメントする

目次