することができますし、あなたのコードは、他の人が使用するか、あなた自身がちょうどそれがクリーナーたい場合は、おそらく終了ハンドラを追加する必要があります。出口ハンドラでは、ループを終了させるフラグを切り替えることができます。while()
次のコードは、このユースケースで100%正常に動作し、信頼できるクロスプラットフォームですが、より複雑なものを実行するには、適切なスレッドセーフなOS固有の関数またはBoostやC++などのものを使用する必要があります11
最初に2つのグローバル変数を宣言し、それらをvolatileにして、コンパイラが常に実際にメモリ値を読み書きするようにします。 volatile宣言しなければ、コンパイラはその値をレジスタに入れて、これを動作させない可能性があります。揮発性の設定では、すべてのループ上のメモリ位置を読み込み、複数のスレッドがあっても正しく動作します。
volatile bool bRunning=true;
volatile bool bFinished=false;
し、代わりにあなたのwhile(1) {}
ループの、自分の終了ハンドラでこの
while(bRunning)
{
dostuff
}
bFinished=true;
に変更し、単にあなたは、オペレーティング・システムを指定していないが、それは見えますbRunning=false;
void ExitHandler()
{
bRunning=false;
while(bFinished==false) { Sleep(1); }
}
を設定あなたがLinuxベースであるように、あなたはこれを必要とするLinux上でハンドラを設定します。
void ExitHandler(int s)
{
bRunning=false;
}
int main()
{
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = ExitHandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
while(bRunning)
{
dostuff
}
...error_handling...
}
コンソールアプリケーションの場合、Windowsでは次のようになります。
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
switch (CEvent)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
bRunning = false;
while (bFinished == false) Sleep(1);
break;
}
return TRUE;
}
int main()
{
SetConsoleCtrlHandler(ConsoleHandler, TRUE);
while(bRunning()
{
dostuff
}
...error_handling...
}
ここでbFinished
をテストして待機する必要があることに注意してください。 Windowsでこれをしないと、別のOS固有のスレッドによって終了ハンドラが呼び出されるため、アプリケーションのシャットダウンに時間がかかりません。 Linuxではこれは必要ではなく、メインスレッドのハンドラを終了して続行する必要があります。
注意すべきもう一つのことは、デフォルトでは、Windowsは終了するまでシャットダウンするのに約5秒しかかかりません。これは多くの場合残念です。多くの時間が必要な場合は、レジストリ設定(悪いアイデア)を変更するか、そのようなものに良いフックを持つサービスを実装する必要があります。あなたの単純なケースのためにそれはうまくいくでしょう。
私はそれをそのまま残し、OSはそれを世話するべきだと思いますか? – buggy3
このケースでは、私は終了信号をフックし、それを使ってプログラムをきれいに終了させたいと思います。一般的には、決して実行されないコードに対しては削除してください。バージョン管理で古いデッドコードを追跡できるようにします。 – Niall
ソケットのクローズを処理する方法、またはコード自体をどうすればいいですか? – rhughes