文法:
#include <csignal> void ( *signal( int シグナル, void (* 関数) (int)) ) (int);
signal()関数は、作成しているプログラムが、引数で指定されたシグナルを受信した場合に呼び出される関数を設定します。関数引数はカスタムのシグナルハンドラを渡すこともできますし、下記の表でマクロとして定義されているハンドラを利用することもできます。これらのマクロはcsignalヘッダで定義されています。
| マクロ | 説明 |
|---|---|
| SIG_DFL | デフォルトのシグナルハンドラ |
| SIG_IGN | シグナルを無視します |
シグナルハンドラを設定できる基本的なシグナルは以下の通りです:
| シグナル | 説明 |
|---|---|
| SIGTERM | 一般的なキャッチ可能な停止シグナルです |
| SIGINT | プログラムへの割り込みです。通常はCtrl-Cで発行されます |
| SIGQUIT | SIGINTと似た、プログラムへの割り込みです |
| SIGKILL | プログラム停止です。キャッチできません |
| SIGHUP | ターミナルとの接続が切れる場合に通知されます |
signal()返り値は、以前定義されていたシグナルハンドラへのポインタです。エラーの発生時はSIG_ERRが返されます。
以下のサンプルは、signal()関数を使用して、ユーザがプログラムを停止したときに任意の数の関数を呼び出します。関数はベクタに保存され、プログラムの終了時に、一つの”clean-up”関数から、すべての関数が呼ばれます:
void f1() { cout << "f1()が呼ばれています..." << endl; } void f2() { cout << "f2()が呼ばれています..." << endl; } typedef void(*endFunc)(void); vector<endFunc> endFuncs; void cleanUp( int dummy ) { for( unsigned int i = 0; i < endFuncs.size(); i++ ) { endFunc f = endFuncs.at(i); (*f)(); } exit(-1); } int main() { // さまざまなシグナルに対して、clean-up関数を設定しています signal( SIGTERM, cleanUp ); signal( SIGINT, cleanUp ); signal( SIGQUIT, cleanUp ); signal( SIGHUP, cleanUp ); // 二つの関数をハンドラから呼ばれるリストに追加します endFuncs.push_back( f1 ); endFuncs.push_back( f2 ); // ユーザが停止するまでループします while( 1 ); return 0; }
関連トピック: raise