2012-12-01 11 views
15

Ich frage mich, ob es sicher ist, eine C++ - Exception in einen OMP-kritischen Abschnitt zu werfen.Eine C++ - Exception in einen omp-kritischen Abschnitt werfen

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

g ++ beschwert sich nicht. Ich bin verwirrt, weil es über return Aussagen im kritischen Abschnitt klagt. Es gibt den Fehler: invalid exit from OpenMP structured block wenn ich

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

So schreibe, warum ist es OK, um den kritischen Abschnitt mit einer Ausnahme zu verlassen, aber es ist nicht OK es mit einer return-Anweisung zu verlassen?

Antwort

17

Nein, es ist nicht in Ordnung, einen kritischen Abschnitt mit Ausnahmen zu verlassen. g++ beschwert sich in diesem Fall nicht, aber es fügt unbemerkt einen impliziten try/catch um den Block des kritischen Abschnitts ein. Beispielsweise den folgenden Code:

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

wird durch den OpenMP Prozessor von GCC 4.7 in abgesenkt:

#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); 

Erreichen der impliziten Einbau-Catch-All-Handler <<<eh_must_not_throw (terminate)>>> Ergebnisse in ganz ungraceful Beendigung:

Die implizite try/catch wird eingefügt, unabhängig von der Anwesenheit eines äußeren try/catch Konstrukts, dh der ex ception würde nie den critical Abschnitt verlassen.

Die OpenMP Standard Aufträge, dass, wenn eine Ausnahme in den meisten Konstrukten OpenMP geworfen wird (parallel, section, master, single, for, critical, task, etc.), wird die Ausführung innerhalb des gleichen Konstrukts, und dass demselben Thread wieder aufnehmen müssen muss die Ausnahme abfangen. Ein Verstoß gegen diese Einschränkung führt zu einem nicht-konformen OpenMP-Code und g++ erzwingt einfach die Konformität, indem er try/catch Blöcke mit Beendigungshandlern in alle diese Konstrukte einfügt.

Wie für den Fehler, wenn eine return Anweisung vorhanden ist, definiert OpenMP einen strcutured Block in C/C++ als:

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.

und auch (für alle Sprachen):

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

Offensichtlich return stellt einen Zweig des Blocks dar, der sich vom einfachen Fallen des unteren Blocks unterscheidet.

Verwandte Themen