11

C++ 標準では、実際に呼び出すstd::set_terminate関数を指定できる関数が提供されています。悲惨な状況でのみ呼び出されるべきであり、それが呼び出されたときに標準が説明している状況は悲惨なものです (たとえば、キャッチされていない例外)。呼び出されたときの状況は、メモリ不足に似ているように思えます。賢明にできることはあまりありません。std::terminatestd::terminatestd::terminate

リソースが確実に解放されるようにするために使用できることを読みましたが、ほとんどのリソースでは、プロセスの終了時に OS によって自動的に処理される必要があります (ファイル ハンドルなど)。理論的には、たとえば、クラッシュのために終了するときにサーバーに特定のメッセージを送信する必要がある場合があります。しかし、ほとんどの場合、OS の処理で十分です。

終了ハンドラーを使用するのが正しいこと (TM) はいつですか?

更新:カスタム終了ハンドラーで何ができるかに興味がある人は、この移植性のないトリックが役立つかもしれません。

4

3 に答える 3

7

これは楽観的です。

ただし、大部分のリソースでは、プロセスの終了時に OS によってこれが自動的に処理される必要があります。

OS が自動的に処理するリソースは、「ファイル ハンドル」と「メモリ」だけです (これは OS によって異なる場合があります)。実際には、他のすべてのリソース (OS によって自動的に処理されるリソースのリストを誰かが持っている場合) は、OS によって手動で解放される必要があります。

最善の策は、terminate() を使用して終了することを避け、スタックを強制的に正しく巻き戻すことによって制御されたシャットダウンを試みることです。これにより、すべてのデストラクタが正しく呼び出され、リソースが (デストラクタを介して) 解放されるようになります。

私がする唯一のことは、問題をログに記録することです。そのため、それが起こったときに、戻ってコードを修正して、それが再び起こらないようにすることができます. 私は自分のコードがリソースの割り当てを解除するためにスタックをうまくアンワインドするのが好きですが、これは物事がうまくいかないときに突然停止するのが好きな人の意見です。

いつ終了するかの私のリストは次のとおりです。

一般に、例外処理メカニズムがスローされた例外のハンドラーを見つけられない場合に呼び出されます。具体的な例は次のとおりです。

  • 例外は main() をエスケープします
    • 注: ここでスタックが巻き戻されるかどうかは実装定義です。したがって、私は常にメインでキャッチしてから再スローします (明示的に処理しない場合)。そうすれば、(すべてのプラットフォームで) スタックの巻き戻しを保証しながら、OS の例外処理メカニズムの利点を引き続き得ることができます。
  • 2 つの例外が同時に伝播します。
    • 別の例外が伝播している間に、例外がデサトラクタをエスケープします。
    • スローされる式は例外を生成します
  • メインの前後の例外。
    • 例外がグローバル オブジェクトのコンストラクター/デストラクターをエスケープする場合。
    • 例外が関数の静的変数のデストラクタをエスケープする場合。(つまり、非ローカル静的オブジェクトのコンストラクター/デストラクターには注意してください)
    • 例外は、atexit() で登録された関数をエスケープします。
  • 現在伝播中の例外がない場合の再スロー。
  • リストされていない例外は、例外指定子リストを持つメソッド/関数をエスケープします。
    • 予期せぬ経由。
于 2009-06-29T15:20:28.673 に答える
0

Martin York's answerで行われた声明と同様に、カスタム終了ハンドラーで私が行う唯一のことは、問題をログに記録して、問題のあるコードを特定して修正できるようにすることです。これは、カスタム終了ハンドラーを使用することが正しいことだと私が見つけた唯一のインスタンスです。


std::terminate()が呼び出される前にスタックが巻き戻されるかどうかは実装定義であるため、キャッチされていない例外を見つけるためにバックトレースを生成するコードを追加することがあります1

1) Linux プラットフォームで GCC を使用している場合、これはうまくいくようです。

于 2010-04-14T23:28:02.783 に答える
-1

適切な質問は、いつ使用するかではなく、終了ハンドラーの呼び出しを回避する方法だと思います。

于 2009-06-29T15:09:03.033 に答える