14

C++2011またはC++2003のいくつかのスレッドに異なる終了例外プロセッサを設定する必要がありset_terminateますか?get_terminate

たとえば、プログラムがあり、terminateハンドラーをfunc_1;に設定した場合。次に、3つのスレッドを開始します。新しいスレッドの終了ハンドラーとは何ですか?すべてのスレッドで、終了ハンドラーをfunc_2最初のスレッド、func_32番目のスレッドなどに設定するとどうなりますか。

N3242(C ++ 2011ドラフト)は、/内また[handler.functions][support.exception]/内でそれについて何も述べていません[exception.terminate]

PS:これらの標準の一般的な実装については、C++2011またはC++2003について回答できます。

PPS:これにはFCDコメントがあります... C++FCDコメントステータスRev.5N3249(2011)

GB 71    18.6.2.4 / 18.8.2.2 / 18.8.3.2   

std::set_new_handler()、、、std::set_unexpected()のスレッドセーフstd::set_terminate()は指定されていないため、関数をスレッドセーフな方法で使用することはできません。

関数のスレッドセーフ保証を指定する必要があり、スレッドセーフな方法でハンドラーを照会およびインストールできるようにするために、新しいインターフェイスを提供する必要があります。

LWG1365 は変更を加えて承認されまし

論文 N3189を参照

4

4 に答える 4

10

17.6.4.7p4は言う:

set_*and関数を呼び出してもget_*、データ競合は発生しません。関数のいずれかへの呼び出しは、同じ関数および対応する関数へset_*の後続の呼び出しと同期する必要があります。set_*get_*

これは、異なるスレッドから呼び出された場合でも、set_*および関数が同じグローバル状態で動作していることを強く意味します。get_*18.8.3に基づくすべての段落では、「現在のハンドラー関数」について説明していますが、スレッドについては他に言及していません。これは、ハンドラー関数がプログラム全体のプロパティであることを示しています。同様に、17.6.4.7には次のものがあります。

2-C++プログラムは実行中に異なるハンドラー関数をインストールする場合があります[...]
3-C++プログラムは、次の関数を呼び出すことにより、現在のハンドラー関数へのポインターを取得できます[...]

これらの段落では、プログラムのコンテキストでの現在のハンドラー関数について説明し、それがプログラムスコープであり、スレッドローカルではないことを示しています。

于 2013-03-12T16:52:55.667 に答える
4

標準では、それは下に言います

18.8.3.2 set_terminate [set.terminate]

terminate_handler set_terminate(terminate_handler f) noexcept;

1効果:例外処理を終了するための現在のハンドラー関数としてfで指定された関数を確立します。

[[noreturn]] void terminate() noexcept;

2効果:現在のterminate_handler関数を呼び出します。[注:このコンテキストでは、デフォルトのterminate_handlerは常に呼び出し可能なハンドラーと見なされます。—エンドノート]

これは、現在の終了ハンドラーをterminate() 呼び出していることがわかります。このセクションでは、プロセスの終了に使用されていることが明確に示されています。これは、実行中のスレッドに関係なく、他のすべての例外処理が失敗したときに呼び出されます。set_handler

終了ハンドラーは1つだけであり、プログラムが終了している場所から常に呼び出されます。

于 2013-03-12T16:54:09.087 に答える
3

規格は正確に指定していません。[set.terminate]状態のみ

[...]例外処理を終了するための現在のハンドラー関数。

ただし、「現在」がグローバルであるかスレッドごとであるかについては言及されていません。したがって、実装によって異なります。

たとえば、MSVC ++の場合: https ://msdn.microsoft.com/en-us/library/t6fk7h29.aspx

マルチスレッド環境では、終了機能はスレッドごとに個別に維持されます。新しいスレッドごとに、独自の終了関数をインストールする必要があります。したがって、各スレッドは独自の終了処理を担当します。

于 2018-02-14T04:11:20.267 に答える
1

C2003にはスレッドがなく、スレッドサポートはベンダー拡張であるため、ベンダー提供のドキュメントのみが答えを持っています。ハンドラーがスレッドごとである場合、ドキュメントにはそのように記載されているはずです。私が知っている実装はありません。

C ++ 2011は、終了ハンドラーのスレッドごとの性質については何も述べていません。C ++ 11ではスレッドを強制終了できないため、スレッドごとに維持することはほとんど意味がありません。そして、正当な理由もあります(google kill + thread + c ++ 11)。したがって、何をするにしても、プログラムは終了する必要があります。プログラムを要求したスレッドに応じて、プログラムを終了する方法が異なるように見えますが、これは誰もが必要とする機能ではありません。

于 2013-03-12T17:27:49.510 に答える