在Openmp区域内抛出std :: runtime_error会导致程序

时间:2016-08-03 07:50:35

标签: c++ exception-handling openmp

我正在尝试加速大型程序的特定部分,异常处理在高级别完成,最初代码看起来像

for(....)
{
...
   if(...)
   {
    throw std:: runtime_error("Terminated by user")
   }
}

现在我已将其更改为

#pragma omp parallel for ...
for(....)
{
...
   if(...)
   {
    throw std:: runtime_error("Terminated by user")
   }
}

现在如果终止被触发,程序崩溃了,我期待这里的异常处理可以以优雅的方式完成,而不需要更改更高级别的东西?

1 个答案:

答案 0 :(得分:2)

OpenMP specification强制要求某个线程抛出的异常必须由同一个线程处理并且在同一个parallel区域内(第2.5节,第49页):

  

throw区域内执行的parallel必须导致执行在同一parallel区域内恢复,并且抛出异常的同一线程必须捕获它。

像GCC这样的编译器通过使用类似于此的catch-all结构包装并行区域的代码来强制执行此要求:

try
{
   ...
}
catch
{
   terminate();
}

因此,任何到达parallel区域末尾的异常都将导致程序中止。

规则实际上更严格,因为它也适用于OpenMP构造,例如forcriticalsingle等。此类构造中抛出的异常必须在同一个构造中捕获构造和抛出它的线程。在您的情况下,for构造导致终止,因为它在parallel区域的隐式catch-all处理程序之前到达了它的隐式catch-all处理程序。