【问题标题】:c++ catch error raised by PPL parallel_forC++ catch 由 PPL parallel_for 引发的错误
【发布时间】:2012-10-02 12:33:59
【问题描述】:

我已经编写了这段代码来捕获 ppl 启动的错误

    try
    {
        parallel_for (m_row_start, m_row_end + 1, [&functionEvaluation,varModel_,this](int i)
        {
             // do things
        });
    }
    catch(const std::exception error_)
    {
        QString t(error_.what());
    }



    try
    {
        return functionEvaluation.combine(plus<double>());
    }
    catch(const std::exception error_)
    {
        QString t(error_.what());
    }

虽然我强烈怀疑它确实引发了异常,但没有发现任何错误(更大的try{}catch(...){} 它捕获了std::exception,没有明确的消息。

我对捕获 ppl 代码中引发的异常的语法是否正确?

【问题讨论】:

    标签: c++ exception parallel-processing try-catch ppl


    【解决方案1】:

    您的语法是正确的,尽管您没有理由不能通过引用来捕获以避免不必要地复制异常对象:

     catch(const std::exception & error_)
    
    1. 检查抛出的异常是否真的来自std::exception
    2. PPL 只允许在所有线程完成后传播异常,您是否有一个仍在运行的线程阻止您看到异常?

    出于调试目的,您可以添加一个额外的 catch 块:

    catch(...)
    {
      cout << "Unknown exception" << endl;
    }
    

    只是为了检查您是否抛出了任何类型的异常,但我不会将其留在生产代码中,因为没有办法有效地处理异常。

    【讨论】:

      【解决方案2】:

      首先,检查抛出了什么。如果你打错了catch,它不会反应。也许它只是 CONST 标记? const-type 与 non-const-type 不同,但实际上我不太记得 catch 是否对 const-volatile 敏感。

      其次,除非有很强的理由,否则总是通过引用来捕捉:

      catch(std::exception& error)
      

      如果不这样做,则会发生异常复制:http://www.parashift.com/c++-faq/what-to-catch.html 复制是指对象复制,而不是重新提升;)

      【讨论】:

      • 谢谢!如果发生异常复制有什么问题(我理解:异常被复制,对吗?)??
      • 异常被复制,就像任何函数或方法的任何传值参数一样。简单地说,复制构造函数被调用,原始异常的内容被调用到局部变量。矛盾的是,通常这是一个小问题,几乎不重要。异常对象通常很小,所以看起来很无辜,但有时会让你头疼。一个经典的例子是,例如,当 stackoverflow 发生异常或内存不足时。在这两种情况下,情况是可用的资源非常很少,并且一旦出现异常
      • 可能会发生...在 catch 块中进行复制会导致第二次溢出或第二次内存不足,并且通常您的代码不会为此做好准备:新的异常将不是在 catch 内抛出,而是在 catch 本身,catch 子句不会运行,新的异常会冒泡,就好像没有 catch 一样。另一件事是针对自定义异常的编写不当的资源管理。随着软件的发展,您通常会创建自己赢得的异常类,或使用一些引发自定义异常的外部库
      • 有时您忘记了,或者该库忘记为异常提供正确的复制构造函数。有时异常有内部动态分配的数据和释放数据的析构函数。默认的 copy-ctor 进行逐字节的复制,如果以这种方式复制带有指针的对象,则副本的析构函数将释放原始数据 --- 但在原始对象中,指针仍指向已释放的数据.稍后,kaboom,当最初抛出的异常将被销毁时。当然,有时只是异常携带
      • 大量跟踪数据,而您根本不想复制它 :) 所有这些都是极端情况和/或与可能的错误有关。所有这些,一旦发生,真的很难找到。通过简单的 get-by-ref 和单个 '&' 来避免所有这些,为什么不呢?您可能会偶然发现一些框架,例如 MFC,其中通常的方法是通过指针抛出和捕获。这正是由于同样的原因,只是他们选择了指针。这个更糟糕的选择,因为您实际上必须抛出一个指向异常的指针,而不是异常。但是,这样的库是存在的。不过,请尝试使用 &。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多