#include < stdexcept >void throwBreak(int aStatus){ signal(SIGINT, NULL); throw std::runtime_error( "signal 'Ctrl-C'." );}// Ctrl-C による正常終了を設定inline void setSigBreak(){ signal(SIGINT, throwBreak..." /> シグナルハンドラーで例外を発生させる - TK's HP

シグナルハンドラーで例外を発生させる - TK's HP

TK's HP ホーム » スポンサー広告 » linux » シグナルハンドラーで例外を発生させる

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

シグナルハンドラーで例外を発生させる

先輩のプログラムの中でCtrl+Cで安全に終了するための処理として、
SIGINTが発生すると throw std::runtime_error( "signal 'Ctrl-C'." ); するというものがあった。

サンプルプログラム

#include < signal.h >
#include < stdexcept >
void throwBreak(int aStatus)
{
signal(SIGINT, NULL);
throw std::runtime_error( "signal 'Ctrl-C'." );
}

// Ctrl-C による正常終了を設定
inline void setSigBreak()
{
signal(SIGINT, throwBreak);
}

int main(int aArgc, char **aArgv)
{
setSigBreak();
try
{
while(1){sleep(1);}
}
catch(std::exception &exception)
{
cerr << endl << "EXCEPTION : " << exception.what() << endl;
}
return 0;
}


ブロッキングされている処理中でも安全に終了できるので便利でこれまで使用していたのだが、
今日新しいプログラムを書いていたところ、

terminate called after throwing an instance of 'std::runtime_error'


と毎回表示されてしまい困った。

調べてみると、
・シグナルハンドラーの中で例外の送出の禁止
http://docs.sun.com/source/806-4838/Exception_Handling.html の非同期例外送出の項
・C++例外がCのコード中を通過するとクラッシュする件
http://d.hatena.ne.jp/yupo5656/20051215/p1

の2つ。

まずそもそもシグナルハンドラーで例外を発生させていた時点でまずかったらしい。

そこで少し改善


#include < signal.h >
#include < stdexcept >

bool gShutOff = false;

void throwBreak(int aStatus)
{
signal(SIGINT, NULL);
gShutOff = true;
}

// Ctrl-C による正常終了を設定
inline void setSigBreak()
{
signal(SIGINT, throwBreak);
}

int main(int aArgc, char **aArgv)
{
setSigBreak();
try
{
while(!gShutOff){sleep(1);}
}
catch(std::exception &exception)
{
cerr << endl << "EXCEPTION : " << exception.what() << endl;
}
return 0;
}


無限ループの条件にgShutOffを追加することにより、正常に終了するようにした。

昔はこの書き方だったけど、try catch の方がループから直接抜け出てくれるから便利だったんですけどね。
上手くは行かないようです。
関連記事
コメント
非公開コメント

トラックバック

http://tclip.blog.fc2.com/tb.php/82-bee4f771

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。