名前空間
変種
操作

std::signal

From cppreference.com
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
 
ヘッダ <csignal> で定義
/* signal-handler */* signal( int sig, /* signal-handler */* handler );
(1)
extern "C" using /* signal-handler */ = void(int);
(2) (説明用*)

シグナル sig のハンドリングを変更します。 handler に応じて、シグナルは無視されるか、デフォルトに設定されるか、またはユーザー定義関数によって処理される可能性があります。

シグナルハンドラが関数に設定され、シグナルが発生した場合、シグナルハンドラの開始直前に std::signal(sig, SIG_DFL) が実行されるかどうかは実装定義です。また、実装は、シグナルハンドラが実行されている間、一部の実装定義されたシグナルの発生を防止することができます。

一部のシグナルについては、プログラムの起動時に実装によって std::signal(sig, SIG_IGN) が呼び出される場合があります。それ以外の場合は、実装は std::signal(sig, SIG_DFL) を呼び出す必要があります。

(注: POSIX は、これらの実装定義の動作を標準化するために sigaction を導入しました)

目次

[編集] パラメータ

sig - シグナルハンドラを設定するシグナル。実装定義の値、または以下のいずれかの値になります。
シグナルの種類を定義する
(マクロ定数) [編集]
ハンドラ - シグナルハンドラ。以下のいずれかである必要があります。
  • SIG_DFL マクロ。シグナルハンドラはデフォルトのシグナルハンドラに設定されます。
  • SIG_IGN マクロ。シグナルは無視されます。
  • 関数へのポインタ。関数のシグネチャは以下と同等である必要があります。
extern "C" void fun(int sig);


[編集] 戻り値

成功した場合は以前のシグナルハンドラ、失敗した場合は SIG_ERR。 (一部の実装では、シグナルハンドラの設定が無効になっている場合があります)。

[編集] シグナルハンドラ

シグナルハンドラとしてインストールされたユーザー定義関数には、以下の制限が課せられます。

シグナルハンドラが std::abort または std::raise の結果として呼び出されない場合 (非同期シグナル)、以下の場合は未定義の動作となります。

  • シグナルハンドラが標準ライブラリ内の任意の関数を呼び出した場合、ただし以下を除く。
  • std::abort
  • std::_Exit
  • std::quick_exit
  • std::signal (最初の引数が現在処理中のシグナルの番号である場合) (非同期ハンドラは自身を再登録できますが、他のシグナルはできません)。
  • シグナルハンドラが、std::atomic または (C++11 以降)volatile std::sig_atomic_t ではない静的記憶域期間を持つ任意のオブジェクトを参照した場合。
(C++17まで)

プレーンなロックフリーアトミック操作とは、<atomic>または <stdatomic.h>(C++23 以降) の関数 f の呼び出しであり、以下の条件を満たすものです。

  • fstd::atomic_is_lock_free 関数である。
  • f がメンバ関数 is_lock_free (例: std::atomic::is_lock_free()) である。
  • fstd::atomic_flag の非静的メンバ関数である。
  • f が非メンバ関数であり、f の最初のパラメータが cv std::atomic_flag* 型である。
  • f が非静的メンバ関数であり、オブジェクト obj に対して呼び出され、obj.is_lock_free()true を返す。
  • f が非メンバ関数であり、f に渡されたすべてのポインタ・トゥ・アトミック引数 arg について、std::atomic_is_lock_free(arg)true を返す。

シグナルハンドラが以下のいずれかを実行した場合、動作は未定義です。

  • プレーンなロックフリーアトミック操作および以下の *シグナルセーフ* 関数以外へのライブラリ関数呼び出し (特に、動的メモリ割り当てはシグナルセーフではありません)。
  • スレッド記憶域期間を持つオブジェクトへのアクセス。
  • dynamic_cast 式。
  • throw 式。
  • try ブロックへのエントリ。
  • 静的変数の初期化で 非ローカル動的初期化 (ODR-use 時の遅延初期化を含む) を行う場合。
  • 別のスレッドが初期化中の静的記憶域期間を持つ任意の変数の初期化完了を待機する場合。
(C++17以降)

SIGFPESIGILLSIGSEGV、または計算例外を指定するその他の実装定義シグナルを処理中にユーザー定義関数が復帰した場合、動作は未定義です。

std::abort または std::raise の結果としてシグナルハンドラが呼び出された場合 (同期シグナル)、シグナルハンドラが std::raise を呼び出した場合の動作は未定義です。

シグナルハンドラに入ると、浮動小数点環境の状態とすべてのオブジェクトの値は未指定ですが、以下は例外です。

(C++11以降)

シグナルハンドラから復帰すると、シグナルハンドラによって変更された、volatile std::sig_atomic_t またはロックフリー std::atomic でない任意のオブジェクトの値は不定です。

(C++14まで)

関数 `signal()` の呼び出しは、結果として生じるシグナルハンドラの呼び出しと 同期します

シグナルハンドラが std::raise の呼び出しによって実行された場合 (同期)、ハンドラの実行は std::raise の呼び出しの *後続* であり、それからの復帰の *前に* 行われ、std::raise と同じスレッドで実行されます。他のシグナルのハンドラの実行は、プログラムの残りの部分とは *順序付けられておらず*、未指定のスレッドで実行されます。

volatile std::sig_atomic_t 型の同じオブジェクトへの 2 つのアクセスは、たとえ一方または両方がシグナルハンドラ内で発生する場合でも、同じスレッド内で発生する場合、データ競合を引き起こしません。各シグナルハンドラ呼び出しについて、シグナルハンドラを呼び出すスレッドによって実行される評価は、2 つのグループ A および B に分割でき、B の評価が A の評価の *前に発生する* ことはなく、そのような volatile std::sig_atomic_t オブジェクトの評価は、A のすべての評価がシグナルハンドラの実行の *前に発生した* かのように値を持ち、シグナルハンドラの実行は B のすべての評価の *前に発生した* かのように動作します。

(C++14以降)

[編集] 注意

POSIX は `signal` がスレッドセーフであることを要求しており、任意のシグナルハンドラから呼び出し可能な、async-signal-safe なライブラリ関数のリストを指定しています。

シグナルハンドラは C リンケージを持つことが期待されており、一般的には C と C++ の共通部分からの機能のみを使用します。ただし、一般的な実装では、C++ リンケージを持つ関数をシグナルハンドラとして使用できます。

[編集]

#include <csignal>
#include <iostream>
 
namespace
{
    volatile std::sig_atomic_t gSignalStatus;
}
 
void signal_handler(int signal)
{
    gSignalStatus = signal;
}
 
int main()
{
    // Install a signal handler
    std::signal(SIGINT, signal_handler);
 
    std::cout << "SignalValue: " << gSignalStatus << '\n';
    std::cout << "Sending signal: " << SIGINT << '\n';
    std::raise(SIGINT);
    std::cout << "SignalValue: " << gSignalStatus << '\n';
}

実行結果の例

SignalValue: 0
Sending signal: 2
SignalValue: 2

[編集] 参照

  • C++23標準 (ISO/IEC 14882:2024)
  • 17.13.5 Signal handlers [support.signal]
  • C++20 standard (ISO/IEC 14882:2020)
  • 17.13.5 Signal handlers [support.signal]
  • C++17 standard (ISO/IEC 14882:2017)
  • 21.10.4 Signal handlers [support.signal]

[編集] 欠陥レポート

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 3756 C++17 std::atomic_flag がシグナルセーフであるか不明瞭でした。 そうである

[編集] 関連項目

特定のシグナルに対してシグナルハンドラを実行する
(関数) [編集]
スレッドと、同じスレッドで実行されるシグナルハンドラとの間のフェンス
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)