OpenMP中的优雅异常处理 [英] Elegant exceptionhandling in OpenMP
问题描述
OpenMP禁止通过异常退出openmp块的代码。因此,我正在寻找一个很好的方法从openmp块获取异常,目的是在主线程中重新抛出它,并在稍后处理。到目前为止,我能够想出的最好的是以下:
OpenMP forbids code which leaves the openmp block via exception. Therefore I'm looking for a nice way of getting the exceptions from an openmp block with the purpose of rethrowing it in the main thread and handling at a later point. So far the best I've been able to come up with is the following:
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(...){}
每个部分,并不得不手动捕获异常。
While this works nicely, rethrowing possible exceptions from the parallel section as soon as the ThreadException
object is destroyed, this construct is still a bit unwieldy to use with putting a try {}catch(...){}
around each section and having to manually capture the exception.
所以我的问题是:有没有人知道一个更优雅(如果是,它是什么样子)?
So my question is: Does anyone know a more elegant (less verbose) way to do this (and if so, what does it look like)?
推荐答案
您可以使用更多的C ++ 11工具语法有点。将此可变参数成员函数添加到 ThreadException
类中:
You can utilize a few more C++11 tools to clean up the syntax a bit. Add this variadic member function to your ThreadException
class:
class ThreadException {
// ...
template <typename Function, typename... Parameters>
void Run(Function f, Parameters... params)
{
try
{
f(params...);
}
catch (...)
{
CaptureException();
}
}
};
然后当在OpenMP结构中调用时使用lambda函数,如下:
Then when calling inside an OpenMP construct use a lambda function like so:
ThreadException e;
#pragma omp parallel for
for (int i = 0; i < n; i++)
{
e.Run([=]{
// code that might throw
// ...
});
}
e.Rethrow()
这篇关于OpenMP中的优雅异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!