C ライブラリ関数 -sigaction()

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

sigaction関数は C 標準ライブラリ内の関数で、特定のシグナルに関連付けられた処理アクションを検査または変更するために使用されます。signal関数と比べると、sigactionより多くの制御とより良い移植性を提供します。

構文

int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);

引数

  • int sig:検査または変更するシグナル番号。一般的なシグナルにはSIGINT、SIGTERM、SIGKILLなどがあります。
  • const struct sigaction *act:新しいシグナル処理アクションへのポインタ。NULL の場合はNULL、現在のシグナル処理アクションは変更されません。
  • struct sigaction *oldact:古いシグナル処理アクションを保存するためのポインタ。NULL の場合はNULL、古いシグナル処理アクションは保存されません。

struct sigaction構造体

struct sigaction {
    void (*sa_handler)(int);           // 信号处理函数指针
    void (*sa_sigaction)(int, siginfo_t *, void *); // 信号处理函数指针(扩展)
    sigset_t sa_mask;                  // 在处理该信号时要阻塞的信号集
    int sa_flags;                      // 修改信号行为的选项
    void (*sa_restorer)(void);         // 恢复函数,已废弃
};

sa_flagsの一般的なオプション

  • SA_RESTART:シグナルによって中断されたシステムコールを自動的に再開します。
  • SA_SIGINFO:使用するsa_sigactionではなくsa_handlerをシグナル処理関数として。
  • SA_NOCLDSTOP:設定されている場合sigであるSIGCHLD、子プロセスが停止または継続しても、そのシグナルは生成されません。

戻り値

  • 成功時には 0 を返します。
  • 失敗時には -1 を返しerrnoエラーの種類を示す errno を設定します。

例

以下は、使用方法を示す簡単なサンプルプログラムです。sigaction関数を使ってSIGINTシグナルの処理ハンドラを設定します。

例

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

// ユーザー定義のシグナル処理関数
void handle_sigint(int sig) {
    printf("Caught signal %d\n", sig);
}

int main() {
    struct sigaction sa;

    // ハンドラを handle_sigint に設定する
    sa.sa_handler = handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    // sigaction を使って新しいシグナル処理アクションを設定する
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    // シグナルを捕捉するまで実行を続けるメインループ
    while (1) {
        printf("Running...\n");
        sleep(1);
    }

    return 0;
}

プログラムをコンパイルして実行すると、出力は次のようになります:

Running...
Running...
Running...
...

Ctrl+C を押すと(送信されるSIGINTシグナル)のとき、出力は次のようになります:

Caught signal 2

プログラムはSIGINTシグナルを捕捉し、ユーザー定義のシグナル処理関数を実行しましたhandle_sigint、その後メインループを続行します。

注意事項

  • sigaction関数は、signal関数よりも豊富な機能を提供し、シグナル処理関数、シグナルマスク、シグナル処理オプションを設定できます。
  • シグナル処理関数はできるだけ短くする必要があります。シグナル処理中は他のシグナルがブロックされるためです。シグナル処理関数の実行時間が長すぎると、プログラムのリアルタイム性に影響を与える可能性があります。
  • 一部のシグナル(例:SIGKILLとSIGSTOP)は捕捉または無視できません。

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

その他の拡張