2-7. シグナル処理
公開日: 10:48 2. 応用編/2-7. シグナル処理
シグナルはオペレーティングシステムによってプロセスへ送られる割り込みであり、プログラムを途中で終了させることができます。 UNIX、LINUX、Mac OS X、Windowsではコントロールキーとcを押すことで割り込みを生成できます。プログラムで補足できないシグナルもありますが、以下のリストはプログラムで補足できるものであり、シグナルに基づいた適切な行動を取ることが可能です。これらのシグナルはC++では<csignal>ヘッダファイルで定義されています。
シグナル | 説明 |
---|---|
SIGABRT | abort(休止)呼び出しなどのプログラムの異常終了 |
SIGFPE | 0除算やオーバーフローになる命令のような誤った算術命令 |
SIGILL | 不正な命令の検出 |
SIGINT | インタラクティブな注意信号の受信 |
SIGSEGV | 記憶領域への不正アクセス |
SIGTERM | プログラムに送られた終了リクエスト |
シグナル関数 signal()
C++のシグナル制御ライブラリは予期せぬ出来事を把握するためにsignal関数を備えています。次の構文はsignal()関数です。void (*signal (int sig, void (*func)(int)))(int);
この関数は2つの引数を取ります。1つ目はシグナル番号を表す整数で、2つ目はシグナル制御関数へのポインタとなります。
signal()関数を使ってSIGINTを補足するC++プログラムを書いてみましょう。どのようなシグナルでもプログラムで補足したいものは、そのシグナルをシグナル関数を使って登録する必要があり、さらにシグナルハンドラと関連付けます。
#include <iostream> #include <csignal> #include <cstdllib> //exit() #include <unistd.h> //sleep() using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received.\n"; // 後片付けはここに記述 // プログラムを終了 exit(signum); } int main () { // シグナルSIGINTとシグナルハンドラの登録 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> #include <cstdllib> //exit() #include <unistd.h> //sleep() using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received.\n"; // 後片付けはここに記述 // プログラムを終了 exit(signum); } int main () { int i = 0; // シグナルSIGINTとシグナルハンドラの登録 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.
0 件のコメント :
コメントを投稿