C ++シグナル処理
シグナルは、オペレーティングシステムによってプロセスに配信される割り込みであり、プログラムを途中で終了させる可能性があります。UNIX、LINUX、Mac OS X、またはWindowsシステムでCtrl + Cを押すと、割り込みを生成できます。
プログラムでキャッチできないシグナルがありますが、プログラムでキャッチでき、シグナルに基づいて適切なアクションを実行できるシグナルのリストは次のとおりです。これらのシグナルは、C ++ヘッダーファイル<csignal>で定義されています。
シニア番号 | 信号と説明 |
---|---|
1 | SIGABRT の呼び出しなど、プログラムの異常終了 abort。 |
2 | SIGFPE ゼロ除算やオーバーフローを引き起こす演算など、誤った算術演算。 |
3 | SIGILL 不正な命令の検出。 |
4 | SIGINT インタラクティブな注意信号の受信。 |
5 | SIGSEGV ストレージへの無効なアクセス。 |
6 | SIGTERM プログラムに送信された終了要求。 |
signal()関数
C ++シグナル処理ライブラリは機能を提供します signal予期しないイベントをトラップします。以下はsignal()関数の構文です-
void (*signal (int sig, void (*func)(int)))(int);
簡単に言うと、この関数は2つの引数を受け取ります。最初の引数は信号番号を表す整数として、2番目の引数は信号処理関数へのポインターとして受け取ります。
signal()関数を使用してSIGINTシグナルをキャッチする簡単なC ++プログラムを書いてみましょう。プログラムでキャッチしたいシグナルが何であれ、を使用してそのシグナルを登録する必要があります。signal関数を作成し、シグナルハンドラーに関連付けます。次の例を調べてください-
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler( int signum ) {
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
int main () {
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
Going to sleep....
Going to sleep....
Going to sleep....
ここで、Ctrl + cを押してプログラムを中断すると、プログラムが信号をキャッチし、次のように出力することで出力されることがわかります。
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
raise()関数
機能別に信号を生成できます raise()、これは引数として整数の信号番号を取り、次の構文を持ちます。
int raise (signal sig);
ここに、 sigは、SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUPのいずれかのシグナルを送信するためのシグナル番号です。以下は、次のように、raise()関数を使用して内部的にシグナルを発生させる例です。
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler( int signum ) {
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
int main () {
int i = 0;
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(++i) {
cout << "Going to sleep...." << endl;
if( i == 3 ) {
raise( SIGINT);
}
sleep(1);
}
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成され、自動的に出力されます-
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.