最終更新日時(UTC):
が更新

履歴 編集

function
<csignal>

std::signal

namespace std {
  extern "C" using signal-handler = void(int); // exposition only
  signal-handler* signal(int sig, signal-handler* func);
}

概要

シグナル番号sigの受け取り後の処理を指定する。

funcの値がSIG_DFLの場合、そのシグナルに対するデフォルトの処理が行われる。 funcの値がSIG_IGNの場合、そのシグナルを無視する。 それ以外の場合、関数funcが実行される。

引数

  • sig: シグナルハンドラを設定するシグナル番号
  • func: シグナルに対する処理。以下のいずれかを指定する。
    • SIG_DFL: そのシグナルに対するデフォルト処理を指定する。
    • SIG_IGN: そのシグナルを無視する。
    • func: シグナルハンドラにする関数へのポインタを示す。

シグナルハンドラ関数の制約

シグナルハンドラ関数は戻り値を持たず、int型の引数を持つ。 この引数にはシグナル番号が格納される。

シグナルハンドラ内で以下以外の処理を行うことは未定義動作である。

  • volatile std::sig_atomic_tオブジェクトへの代入
  • abort関数
  • _Exit関数
  • quick_exit関数
  • atomic引数がロックフリーである場合の<stdatomic.h>内の関数
  • 任意のatomic引数を持つatomic_is_lock_free関数
  • signal関数(ただし、ハンドラを起こしたシグナル番号に対する呼び出しに限る)

戻り値

成功した場合、指定されたシグナルに対する直前のハンドラを返す。 それ以外の場合はSIG_ERRを返す

備考

マルチスレッド内でのこの関数の動作は未定義

#include <csignal>
#include <iostream>

volatile std::sig_atomic_t flag = 0;

void signal_handler(int sig)
{
  flag = 1;
  // std::cout << "signal: " << sig << std::endl; 未定義動作
}

int main()
{
  std::signal(SIGINT, signal_handler);
  while (!flag) {
    //処理
  }
  if (flag) {
    std::cout << "caught SIGINT" << std::endl;
  }
  return 0;
}

出力例

caught SIGINT