std:: signal
|
定義済みヘッダー
<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 | - |
シグナルハンドラを設定するシグナル。実装定義の値または以下のいずれかの値を指定できます:
|
||||||
| handler | - |
シグナルハンドラ。以下のいずれかを指定する必要があります:
|
戻り値
成功時は前のシグナルハンドラ、失敗時は SIG_ERR を返す(一部の実装ではシグナルハンドラの設定が無効化されている場合がある)。
シグナルハンドラ
シグナルハンドラとしてインストールされるユーザー定義関数には以下の制限が課されます。
|
シグナルハンドラが std::abort または std::raise の結果として呼び出されない場合(非同期シグナル)、以下の場合の動作は未定義です:
|
(C++17まで) |
|
プレーンロックフリーアトミック操作 とは、 <atomic> または <stdatomic.h> (C++23以降) からの関数 f の呼び出しであり、以下のいずれかの条件を満たすもの:
シグナルハンドラが以下のいずれかを実行する場合、動作は未定義です:
|
(C++17以降) |
ユーザー定義関数が SIGFPE 、 SIGILL 、 SIGSEGV または計算例外を指定するその他の実装定義シグナルを処理中に戻った場合、動作は未定義です。
シグナルハンドラが std::abort または std::raise (同期シグナル)の結果として呼び出された場合、シグナルハンドラが std::raise を呼び出すと動作は未定義です。
|
シグナルハンドラのエントリ時点では、 浮動小数点環境 の状態と全てのオブジェクトの値は未規定である。ただし以下を除く:
シグナルハンドラからのリターン時、シグナルハンドラによって変更されたオブジェクトの値で、 volatile std:: sig_atomic_t またはロックフリーな std::atomic でないものは不定である。 |
(C++14まで) | ||
|
関数
シグナルハンドラが
std::raise
の呼び出しの結果として(同期的に)実行される場合、ハンドラの実行は
同じ volatile std:: sig_atomic_t 型のオブジェクトへの2つのアクセスは、両方が同じスレッドで発生する場合、1つ以上がシグナルハンドラ内で発生してもデータ競合を引き起こさない。 各シグナルハンドラの起動について、シグナルハンドラを呼び出すスレッドによって実行される評価は、グループAとBの2つに分割でき、Bの評価がAの評価に対して happen-before 関係を持たず、かつそのような volatile std:: sig_atomic_t オブジェクトの評価は、Aの全ての評価がシグナルハンドラの実行に対して happened-before であり、シグナルハンドラの実行がBの全ての評価に対して happened-before であるかのように値を取る。 |
(C++14以降) |
注記
POSIXでは
signal
がスレッドセーフであることを要求しており、
任意のシグナルハンドラから呼び出せる非同期シグナルセーフなライブラリ関数のリスト
を規定しています。
シグナルハンドラは Cリンケージ を持つことが期待され、一般的にはCとC++の共通サブセットの機能のみを使用すべきです。しかし、一般的な実装ではC++リンケージを持つ関数をシグナルハンドラとして使用することが許可されています。
例
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // シグナルハンドラをインストール 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 シグナルハンドラ [support.signal]
- C++20 標準 (ISO/IEC 14882:2020):
-
- 17.13.5 シグナルハンドラ [support.signal]
- C++17規格 (ISO/IEC 14882:2017):
-
- 21.10.4 シグナルハンドラ [support.signal]
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3756 | C++17 |
std::atomic_flag
がシグナルセーフであるか不明確であった
|
シグナルセーフである |
関連項目
|
特定のシグナルに対するシグナルハンドラを実行する
(関数) |
|
|
(C++11)
|
同じスレッドで実行されるスレッドとシグナルハンドラ間のフェンス
(関数) |
|
Cドキュメント
for
signal
|
|