[解決済み] スレッド間で例外を伝播させるにはどうしたらいいですか?
質問
1つのスレッドが呼び出す関数があります(これをメインスレッドと名付けます)。関数の本体内で、CPU に集約された作業を行うために複数のワーカスレッドを生成し、すべてのスレッドが終了するのを待ち、その後メインスレッドで結果を返します。
その結果、呼び出し元は関数を素直に使うことができ、内部では複数のコアを使用することになります。
今のところすべて良好です。
問題は、例外の処理です。 ワーカスレッドで例外が発生してアプリケーションがクラッシュするのは困ります。 関数の呼び出し元が、メイン スレッドで例外をキャッチできるようにしたいのです。 ワーカスレッドで例外をキャッチし、それをメインスレッドに伝搬して、そこから巻き戻しを続けさせなければなりません。
どのようにしてこれを行うのでしょうか。
一番思いつくのは
- ワーカスレッドで様々な例外をキャッチする(std::exceptionといくつかの独自のもの)。
- 例外の型とメッセージを記録します。
- ワーカスレッドで記録されたどのようなタイプの例外でも再スローする、メインスレッド上の対応するスイッチステートメントを用意する。
これは、限られた例外タイプしかサポートしないという明らかな欠点があり、新しい例外タイプが追加されるたびに修正が必要になります。
どのように解決するのか?
C++11 では
exception_ptr
型が導入され、スレッド間で例外を転送することができるようになりました。
#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>
static std::exception_ptr teptr = nullptr;
void f()
{
try
{
std::this_thread::sleep_for(std::chrono::seconds(1));
throw std::runtime_error("To be passed between threads");
}
catch(...)
{
teptr = std::current_exception();
}
}
int main(int argc, char **argv)
{
std::thread mythread(f);
mythread.join();
if (teptr) {
try{
std::rethrow_exception(teptr);
}
catch(const std::exception &ex)
{
std::cerr << "Thread exited with exception: " << ex.what() << "\n";
}
}
return 0;
}
あなたの場合、複数のワーカスレッドを持っているので、1つの
exception_ptr
をそれぞれ保持する必要があります。
なお
exception_ptr
は共有 ptr ライクなポインタなので、少なくとも1つの
exception_ptr
を各例外を指しておく必要があります。
Microsoft 固有のもの: SEH 例外を使用する場合 (
/EHa
) を使用する場合、サンプルコードはアクセス違反のような SEH 例外も送りますが、それはあなたが望むものではない可能性があります。
関連
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 複数の例外を1行でキャッチする(ブロックを除く)
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] Linux上で動作するC++コードのプロファイリングを行うにはどうすればよいですか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] 最近のPythonでカスタム例外を宣言する適切な方法?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件