std::signal
ヘッダ <csignal> で定義 | ||
/*signal-handler*/* signal(int sig, /*signal-handler*/* handler); | (1) | |
extern"C"using/*signal-handler*/=void(int);// exposition-only | (2) | |
シグナル sig
のためのハンドラを設定します。 シグナルハンドラは、デフォルトの処理を行う、シグナルを無視する、またはユーザ定義の関数が呼ばれるように設定することができます。
シグナルハンドラが関数に設定され、シグナルが発生したとき、シグナルハンドラの開始直前に std::signal(sig, SIG_DFL) が実行されるかどうかは処理系定義です。 また処理系は、シグナルハンドラを実行している間、処理系定義のシグナルの集合が発生しないように防ぐかもしれません。
いくつかのシグナルについては、処理系はプログラム開始時に std::signal(sig, SIG_IGN) を呼んでも構いません。 その他のシグナルについては、処理系は std::signal(sig, SIG_DFL) を呼ばなければなりません。
(ノート: POSIX はこれらの処理系定義の動作を標準化するための sigaction を導入しました)
目次 |
[編集]引数
sig | - | シグナルハンドラを設定するシグナル。 処理系定義の値、または以下の値のいずれか。
| ||||||
handler | - | シグナルハンドラ。 以下のいずれかでなければなりません。
|
[編集]戻り値
成功した場合は以前のシグナルハンドラ、失敗した場合は SIG_ERR (処理系によってはシグナルハンドラの設定は無効化されていることがあります)。
[編集]シグナルハンドラ
シグナルハンドラとしてインストールされるユーザ定義の関数には、以下の制限が課されます。
std::abort または std::raise の結果としてではなくシグナルハンドラが呼ばれた場合 (非同期シグナル)、以下は未定義動作となります。
| (C++17未満) |
任意のシグナルハンドラが以下のいずれかを行った場合、動作は未定義です。
| (C++17以上) |
SIGFPE, SIGILL, SIGSEGV またはその他の計算上の例外を表す処理系定義のシグナルを処理するとき、ユーザ定義の関数が戻ると、動作は未定義です。
std::abort または std::raise の結果としてシグナルハンドラが呼ばれた場合 (同期シグナル)、シグナルハンドラが std::raise を呼ぶと、動作は未定義です。
シグナルハンドラの開始時、以下を除くすべてのオブジェクトの値および浮動小数点数環境の状態は未規定です。
シグナルハンドラから戻るとき、 volatilestd::sig_atomic_t またはロックフリーな std::atomic 以外の、シグナルハンドラで変更されたあらゆるオブジェクトの値は、不定になります。 | (C++14未満) | ||
関数 std::raise の呼び出しの結果としてシグナルハンドラが (同期的に) 実行された場合、そのハンドラの実行は、 volatilestd::sig_atomic_t 型の同じオブジェクトへの2つのアクセスは、両方が同じスレッドで行われれば、シグナルハンドラ内で行われても、データ競合を発生しません。 シグナルハンドラの各呼び出しについて、シグナルハンドラを呼び出すスレッドで行われる評価は、 A 内の評価に対して先行発生する評価が B になく、 そのような volatilestd::sig_atomic_t オブジェクトの評価がシグナルハンドラの実行に対して先行発生する A 内のすべての評価を通して値を取得し、シグナルハンドラの実行が B 内のすべての評価に対して先行発生するような、2つのグループ A と B に分割できます。 | (C++14以上) |
[編集]ノート
POSIX は、 signal
がスレッドセーフであることを要求しており、任意のシグナルハンドラから呼ぶことができる非同期シグナルセーフなライブラリ関数の一覧を規定しています。
シグナルハンドラは、 C リンケージを持ち、一般的に、 C と C++ の共通のサブセットの機能のみを使用すると期待されています。 C++ リンケージを持つ関数がシグナルハンドラとして使用できるかどうかは処理系定義です。
[編集]例
#include <csignal>#include <iostream> namespace{volatilestd::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++11) | 同じスレッドで実行されるシグナルハンドラとの間のフェンス (関数) |
signal の C言語リファレンス |