【发布时间】:2012-08-06 12:43:52
【问题描述】:
OpenMP 禁止通过异常离开 openmp 块的代码。因此,我正在寻找一种从 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(); }
}
虽然这很好用,一旦ThreadException 对象被销毁,就从并行部分重新抛出可能的异常,但在每个部分周围放置try {}catch(...){} 并且必须手动捕获例外。
所以我的问题是:有谁知道更优雅(不那么冗长)的方式来做到这一点(如果有,它是什么样子的)?
【问题讨论】:
-
当两个或多个线程抛出异常(可能不同)时,您将如何处理?
-
@HristoIliev:忽略其中一个(因为无论如何我不能抛出一个异常),只重新抛出最后一个。
-
从析构函数中抛出是非法的(我使用了一个这样做的库,它给我带来了很多麻烦,直到我弄清楚为什么我的应用程序在没有捕获异常的情况下一直中止)。您必须在并行部分之后致电
except.Rethrow()。如果发生异常时您不想执行的并行部分之后有顺序代码,这会更好。 -
我认为使用
std::mutex可能会导致未定义的行为。见stackoverflow.com/a/53516587/5861244。但是,#pragma omp critical应该在这里工作。
标签: c++ exception-handling c++11 openmp