2012-12-01 22 views
15

我想知道在OMP臨界區內拋出C++異常是否安全。在omp臨界區內拋出C++異常

#pragma omp critical (my_critical_section) 
{ 
    ... 
    throw my_exception("failed") 
    ...  
} 

g ++沒有抱怨。我很困惑,因爲它在關鍵部分中抱怨return陳述。它返回的錯誤:當我寫

#pragma omp critical (my_critical_section) 
{ 
    ... 
    return; 
    ...  
} 

那麼invalid exit from OpenMP structured block,爲什麼它確定離開與異常的關鍵部分,但它是不OK與return語句離開嗎?

回答

17

不,可以將臨界區留下例外情況。 g++在這種情況下不會抱怨,但是會在關鍵部分的塊周圍悄悄插入一個隱含的try/catch。例如下面的代碼:

#pragma omp critical (my_crit) 
{ 
    throw 3; 
} 

被下調的GCC 4.7 OpenMP的處理器爲:

#pragma omp critical (my_crit) 
__builtin_GOMP_critical_name_start (&.gomp_critical_user_my_crit); 
try 
    { 
    D.20639 = __cxa_allocate_exception (4); 
    try 
     { 
     MEM[(int *)D.20639] = 3; 
     } 
    catch 
     { 
     __cxa_free_exception (D.20639); 
     } 
    __cxa_throw (D.20639, &_ZTIi, 0B); 
    } 
catch 
    { 
    <<<eh_must_not_throw (terminate)>>> 
    } 
__builtin_GOMP_critical_name_end (&.gomp_critical_user_my_crit); 

到達隱內置包羅萬象的處理<<<eh_must_not_throw (terminate)>>>結果相當不適度終止:

terminate called after throwing an instance of 'int' 
Abort trap: 6 

插入暗含的try/catch,不管存在外部try/catch構造,即ex ception永遠不會離開critical部分。

OpenMP標準的任務,如果一個異常被最OpenMP構造(parallelsectionmastersingleforcriticaltask等)內引發,執行必須相同構建內和相同的線程恢復必須抓住這個例外。違反此限制會導致不符合OpenMP代碼,並且g++只需在所有此類結構中插入帶終止處理程序的try/catch塊即可強制執行一致性。

至於當return語句存在錯誤,OpenMP的定義在C/C++作爲strcutured塊:

For C/C++, an executable statement, possibly compound, with a single entry at the top and a single exit at the bottom, or an OpenMP construct.

,並且還(對於所有語言):

The point of exit cannot be a branch out of the structured block.

顯然return構成塊的分支,不同於塊的底部的簡單下降。