C標準ライブラリ -<signal.h>

概要

<signal.h>C標準ライブラリ内のヘッダファイルで、シグナルを処理するために使用されます。

signal.hヘッダファイルは1つの変数型を定義し、sig_atomic_t2つの関数呼び出しといくつかのマクロで、プログラム実行中に報告されるさまざまなシグナルを処理します。

シグナルは非同期通知メカニズムであり、特定のイベントが発生したときにプロセスが事前定義された処理関数を実行できるようにします。

以下は、signal 関数を使用して SIGINT シグナル(通常は Ctrl+C によって生成されます)を捕捉する方法を示す簡単なサンプルプログラムです。

例

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

// プログラムが終了すべきかどうかを示すグローバル変数
volatile sig_atomic_t stop = 0;

void handle_sigint(int sig) {
    printf("Caught signal %d\n", sig);
    stop = 1; // 終了フラグを設定
}

int main() {
    // SIGINT シグナルのハンドラを handle_sigint 関数に設定
    signal(SIGINT, handle_sigint);

    while (!stop) { // 終了すべきかどうかを確認
        printf("Running...\n");
        sleep(1);
    }

    printf("Exiting...\n");

    return 0;
}

上記のコードでは、プログラムの実行中にユーザーが押すとCtrl+C、SIGINT シグナルが捕捉され、handle_sigint 関数が呼び出され、シグナル番号が出力されます。

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

Running...
Running...
Running...
^CCaught signal 2
Exiting...

コード解析:

  • volatile sig_atomic_t stop = 0;:グローバル変数を定義しますstop、プログラムが終了すべきかどうかを示すために使用されます。volatileキーワードを使用して、コンパイラがその変数へのアクセスを最適化しないことを保証します。シグナルハンドラ内で変更される可能性があるためです。sig_atomic_t型は、その変数へのアクセスがアトミックであることを保証します。
  • にhandle_sigintシグナル処理関数では、stopを1に設定して、プログラムが終了すべきことを示します。
  • メインループでは、stop変数の値を確認し、1に設定されている場合はループを抜けてプログラムを終了します。

ライブラリ変数

以下は、ヘッダファイル signal.h で定義されている変数型です:

番号変数 & 説明
1sig_atomic_t
これはint型で、シグナルハンドラ内で変数として使用されます。これはオブジェクトの整数型であり、非同期シグナルが存在する場合でも、そのオブジェクトはアトミックエンティティとしてアクセスできます。
2sigset_t
シグナルセットを表すためのデータ型です。

ライブラリマクロ

<

C標準ライブラリでは、SIG_接頭辞のマクロはsignal関数と一緒に使用され、シグナルの動作を定義および処理します。以下は一般的なSIG_マクロとその用途です:

番号マクロ & 説明
1 SIG_DFL
シグナルのデフォルトハンドラを表します。このマクロを使用すると、シグナルをデフォルトの動作に戻すことができます。
2 SIG_ERR
シグナル処理関数の設定が失敗したことを示す戻り値です。
3 SIG_IGN
シグナルを無視します。

シグナルの種類:

定数説明
SIGABRT由 abort関数によって生成されるシグナルで、異常終了を表します。
SIGALRM由 alarm関数によって設定されたタイマー満了シグナル
SIGBUS不正なメモリアクセス(例:アライメントされていないメモリアドレスへのアクセス)
SIGCHLD子プロセスの状態変更(終了または停止)
SIGCONT一時停止されたプロセスの実行を継続
SIGFPE算術エラー(例:ゼロ除算エラー、浮動小数点例外)
SIGHUPハングアップシグナル(通常、端末の切断を検出するために使用されます)
SIGILL不正な命令
SIGINT割り込みシグナル(通常は Ctrl+C によって生成されます)
SIGKILL即時終了シグナル(捕捉または無視できません)
SIGPIPE読み取りプロセスのないパイプへのデータ書き込み
SIGQUIT端末終了シグナル(通常は Ctrl+\ によって生成されます)、コアダンプを生成します。
SIGSEGVセグメンテーションフォルト(不正なメモリアクセス)
SIGSTOPプロセスの実行を停止します(捕捉または無視できません)
SIGTERM終了シグナル
SIGTSTPプロセスを一時停止します(通常は Ctrl+Z によって生成されます)
SIGTTINバックグラウンドプロセスが端末からデータを読み取るときに生成されるシグナル
SIGTTOUバックグラウンドプロセスが端末にデータを書き込むときに生成されるシグナル
SIGUSR1ユーザー定義シグナル 1
SIGUSR2ユーザー定義シグナル 2
SIGPOLLI/O イベント(SIGIO の代替)
SIGPROFタイマー満了シグナル(setitimerによって設定されるプロファイリングタイマー)
SIGSYS不正なシステムコール
SIGTRAPブレークポイントまたはトラップ命令
SIGURGソケットの緊急状態シグナル
SIGVTALRM仮想クロックタイマー満了シグナル
SIGXCPUCPU 時間制限を超過
SIGXFSZファイルサイズ制限を超過

ライブラリ関数

以下は、ヘッダファイル signal.h で定義されている関数です:

関数 説明
void (*signal(int sig, void (*func)(int)))(int); シグナルハンドラを設定します。
int raise(int sig); 現在のプロセスにシグナルを送信します。
int kill(pid_t pid, int sig); 指定されたプロセスにシグナルを送信します。
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); ブロックされたシグナルセットを確認または変更します。
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact); シグナルハンドラを確認または変更します。
int sigsuspend(const sigset_t *mask); 現在のシグナルマスクを一時的に置き換え、シグナルを捕捉するまでプロセスを一時停止します。
int sigpending(sigset_t *set); 保留中のシグナルセットを確認します。
int sigemptyset(sigset_t *set); シグナルセットを空集合として初期化します。
int sigfillset(sigset_t *set); シグナルセットを全シグナル集合として初期化します。
int sigaddset(sigset_t *set, int signum); 指定されたシグナルをシグナルセットに追加します。
int sigdelset(sigset_t *set, int signum); 指定されたシグナルをシグナルセットから削除します。
int sigismember(const sigset_t *set, int signum); 指定されたシグナルがシグナルセット内にあるかどうかを確認します。
void abort(void); 発生SIGABRTシグナルが発生し、プロセスが異常終了します。
unsigned int alarm(unsigned int seconds); 指定された秒数後に送信しますSIGALRMシグナルを呼び出しプロセスに送信します。
int pause(void); シグナルを捕捉するまでプロセスを一時停止します。
void psignal(int sig, const char *s); シグナルの説明情報を出力します。
char *strsignal(int sig); シグナルの説明文字列を返します。
int sigwait(const sigset_t *set, int *sig); シグナルをブロックして待機し、処理します。
その他の拡張