OpenMP並列化領域内からC++例外を送出する場合、例外を送出したスレッドと同一スレッド上で例外catchを行う必要がある。すなわちOpenMPスレッドをまたぐC++例外伝搬は行われず、またOpenMP並列化領域の中から外へC++例外が送出されてはならない。このルールに反する場合、実行時クラッシュなどを引き起こす可能性がある。
#pragma omp parallel for for (int i = 0; i < 100; i++) { //... throw i; // NG: parallel領域を超えてC++例外が送出される }
#include <memory> #include <new> #pragma omp parallel thread_num(2) { try { //... auto = std::make_shared<T>(/*...*/); // ::new //... } catch (const std::bad_alloc& e) { // OK: 同一スレッド内でcatchすれば問題ない } }
OpenMP C/C++ API v2.0仕様*1 1.2 Definition of Terms, 2.3 parallel Constructsより該当箇所を引用。
structured block
A structured block is a statement (single or compound) that has a single entry and a single exit. No statement is a structured block if there is a jump into or out of that statement (including a call tolongjmp
(3C) or the use ofthrow
, but a call toexit
is permitted). (snip)
dynamic extent
Restrictions to the parallel directive are as follows:
- (snip)
- A
throw
executed inside a parallel region must cause execution to resume within the dynamic extent of the same structured block, and it must be caught by the same thread that threw the exception.- (snip)
関連URL