OpenMP prohíbe el código que deja el bloque de openmp por excepción. Por lo tanto, estoy buscando una buena manera de obtener las excepciones de un bloque openmp con el propósito de volver a lanzarlo en el hilo principal y manejarlo en un momento posterior. Hasta ahora el mejor que he podido para llegar a es el siguiente:Elegante manejo de excepción en 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(); }
}
Aunque esto funciona muy bien, Regeneración de las posibles excepciones de la sección paralela, tan pronto como el objeto ThreadException
se destruye, esta construcción sigue siendo una Es un poco difícil de usar al colocar un try {}catch(...){}
alrededor de cada sección y tener que capturar manualmente la excepción.
Así que mi pregunta es: ¿Alguien sabe de una manera más elegante (menos detallada) para hacer esto (y si es así, cómo se ve)?
¿Cómo manejaría el caso de que dos o más hilos que generan excepciones (posiblemente diferentes)? –
@HristoIliev: Ignorando uno de ellos (ya que no puedo arrojar más de una excepción) y solo volviendo a lanzar el último. – Grizzly
Lanzar desde un destructor es ilegal (he usado una biblioteca que hizo esto, y me provocó muchos dolores de cabeza hasta que descubrí por qué mi aplicación seguía abortando sin detectar la excepción). Tendría que llamar a 'except.Rethrow()' después de la sección paralela. Esto sería mejor de cualquier forma si hay un código secuencial después de la sección paralela que no desea ejecutar si se produce una excepción. –