例外とキャンセル

インテル® スレッディング・ビルディング・ブロック (インテル® TBB) は、例外とキャンセルをサポートしています。インテル® TBB アルゴリズム内部のコードが例外をスローすると、一般に次のステップが発生します。

  1. 例外がキャプチャーされます。アルゴリズム内部のほかの例外は無視されます。

  2. アルゴリズムがキャンセルされます。保留中の反復は実行されません。「キャンセルと入れ子の並列処理」で説明されているように、内部で入れ子になっているインテル® TBB の並列処理がある場合は、入れ子になっている並列処理もキャンセルされます。

  3. アルゴリズムのすべての部分が停止すると、アルゴリズムを呼び出したスレッドで例外がスローされます。

ステップ 3 でスローされる例外は、オリジナルの例外、または captured_exception 型のサマリーです。スレッド間の例外を伝えるには C++ std::exception_ptr 機能のサポートが必要になるため、現在のシステムでは通常は後者が発生します。この機能のサポートがコンパイラーに含まれるようになれば、インテル® TBB の将来のバージョンではオリジナルの例外をスローするようになるでしょう。このため、コードでいずれか一方の例外をキャッチできることを確認してください。次のコードは、例外処理のサンプルです。

#include "tbb/tbb.h"
#include <vector>
#include <iostream>
 
using namespace tbb;
using namespace std;
 
vector<int> Data;
 
struct Update {
    void operator()( const blocked_range<int>& r ) const {
        for( int i=r.begin(); i!=r.end(); ++i )
            Data.at(i) += 1;
    }
};
 
int main() {
    Data.resize(1000);
    try {
        parallel_for( blocked_range<int>(0, 2000), Update());
    } catch( captured_exception& ex ) {
       cout << "captured_exception: " << ex.what() << endl;
    } catch( out_of_range& ex ) {
       cout << "out_of_range: " << ex.what() << endl;
    }
    return 0;
}

parallel_for は、要素が 1000 個のベクトルで 2000 個の要素を反復しようとします。このため、式 Data.at(i) はアルゴリズムの実行中に例外 std::out_of_range をスローすることがあります。例外が発生すると、アルゴリズムはキャンセルされ、呼び出し側で例外が parallel_for にスローされます。