在omp关键节内引发C++异常
Throwing a C++ exception inside an omp critical section
我想知道在OMP关键部分内抛出C++异常是否安全。
#pragma omp critical (my_critical_section)
{
...
throw my_exception("failed")
...
}
g++没有抱怨。我很困惑,因为它抱怨关键部分中的return
语句。当我写时,它返回错误:invalid exit from OpenMP structured block
#pragma omp critical (my_critical_section)
{
...
return;
...
}
那么,为什么在关键部分留下一个异常是可以的,而在关键部分保留一个返回语句是不可以的呢?
不,在关键部分保留异常是不可以的。g++
在这种情况下没有抱怨,但它在关键部分的块周围无声地插入了一个隐含的try/catch
。例如以下代码:
#pragma omp critical (my_crit)
{
throw 3;
}
被GCC 4.7的OpenMP处理器降低为:
#pragma omp critical (my_crit)
__builtin_GOMP_critical_name_start (&.gomp_critical_user_my_crit);
try
{
D.20639 = __cxa_allocate_exception (4);
try
{
MEM[(int *)D.20639] = 3;
}
catch
{
__cxa_free_exception (D.20639);
}
__cxa_throw (D.20639, &_ZTIi, 0B);
}
catch
{
<<<eh_must_not_throw (terminate)>>>
}
__builtin_GOMP_critical_name_end (&.gomp_critical_user_my_crit);
达到隐含的内置catch-all处理程序<<<eh_must_not_throw (terminate)>>>
会导致非常不合理的终止:
terminate called after throwing an instance of 'int'
Abort trap: 6
隐式try/catch
被插入,而不管外部try/catch
构造的存在,即异常永远不会离开critical
部分。
OpenMP标准规定,如果在大多数OpenMP构造(parallel
、section
、master
、single
、for
、critical
、task
等)中引发异常,则必须在同一构造中恢复执行,并且同一线程必须捕获该异常。违反此限制会导致不一致的OpenMP代码,g++
只是通过在所有此类构造中插入带有终止处理程序的try/catch
块来强制执行一致性。
对于出现return
语句时的错误,OpenMP将C/C++中的结构化块定义为:
对于C/C++,一个可执行语句,可能是复合语句,顶部有一个入口,底部有一个出口,或者是一个OpenMP构造。
以及(适用于所有语言):
出口点不能是结构化块的分支。
显然,return
构成了块的一个分支ouf,不同于块底部的简单下降。
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 尝试使用智能指针时引发异常
- 函数如何通知用户它基于函数原型抛出异常?
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Pytorch torch.cholesky忽略异常