OpenMP zabrania kodu, który opuszcza blok OpenMP przez wyjątek. Dlatego szukam ładnego sposobu na uzyskanie wyjątków z bloku OpenMP w celu ponownego wrzucenia go w główny wątek i obsługi w późniejszym czasie. Do tej pory najlepszy byłem w stanie wymyślić, to:Elegant exceptionhandling w OpenMP
class ThreadException {
std::exception_ptr Ptr;
std::mutex Lock;
public:
ThreadException(): Ptr(nullptr) {}
~ThreadException(){ this->Rethrow(); }
void Rethrow(){
if(this->Ptr) std::rethrow_exception(this->Ptr);
}
void CaptureException() {
std::unique_lock<std::mutex> guard(this->Lock);
this->Ptr = std::current_exception();
}
};
//...
ThreadException except;
#pragma omp parallel
{
try {
//some possibly throwing code
}
catch(...) { except.CaptureException(); }
}
Chociaż to działa dobrze, Ponowne generowanie możliwych wyjątków z sekcji równoległej jak tylko obiekt ThreadException
jest zniszczony, konstrukcja ta jest nadal Trochę niezręczny w użyciu przy wstawianiu try {}catch(...){}
wokół każdej sekcji i konieczności ręcznego przechwytywania wyjątku.
Moje pytanie brzmi: czy ktokolwiek zna bardziej elegancki (mniej gadatliwy) sposób na zrobienie tego (a jeśli tak, jak to wygląda)?
W jaki sposób można obsłużyć przypadek, gdy dwa lub więcej wątków rzucać wyjątki (możliwe inne)? –
@HristoIliev: Ignorując jednego z nich (ponieważ nie mogę wyrzucić ani jednego wyjątku) i tylko ponownie wyrzucając ostatnią. – Grizzly
Rzucanie z destruktora jest nielegalne (użyłem biblioteki, która to zrobiła i spowodowało to wiele bólów głowy, dopóki nie zorientowałem się, dlaczego moja aplikacja ciągle przerywa, nie wychwytując wyjątku). Będziesz musiał wywołać 'except.Rethrow()' po sekcji równoległej. Byłoby lepiej w każdym przypadku, gdyby po sekcji równoległej był kod sekwencyjny, którego nie chcesz wykonywać, jeśli wystąpił wyjątek. –