OpenMP 禁止通过异常离开 openmp block 的代码。因此,我正在寻找一种从 openmp block 中获取异常的好方法,目的是将其重新抛出到主线程中并在以后进行处理。到目前为止,我能想到的最好的是:
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 时仍然有点笨拙(...){}
围绕每个部分并且必须手动捕获异常。
所以我的问题是:有没有人知道更优雅(更简洁)的方法来做到这一点(如果是这样,它看起来像什么)?
最佳答案
您可以使用更多的 C++11 工具稍微清理一下语法。将此可变参数成员函数添加到您的 ThreadException
类:
class ThreadException {
// ...
template <typename Function, typename... Parameters>
void Run(Function f, Parameters... params)
{
try
{
f(params...);
}
catch (...)
{
CaptureException();
}
}
};
然后在 OpenMP 构造内部调用时使用 lambda 函数,如下所示:
ThreadException e;
#pragma omp parallel for
for (int i = 0; i < n; i++)
{
e.Run([=]{
// code that might throw
// ...
});
}
e.Rethrow()
关于c++ - OpenMP 中优雅的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11828539/