OpenMP中的优雅异常处理 [英] Elegant exceptionhandling in OpenMP

查看:317
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆