可以通过异常指针"duplicated"异常吗?
Can exceptions be "duplicated" via exception pointers?
对于一些多线程代码,我希望捕获所有异常并将它们传递给单个异常处理线程。以下是消息传递框架:
#include <exception>
struct message
{
virtual ~message() = default;
virtual void act() = 0;
};
struct exception_message : message
{
std::exception_ptr ep;
virtual void act()
{
std::rethrow_exception(ep);
}
// ...
};
这是一个用例:
try
{
// ...
}
catch (...)
{
exception_message em { std::current_exception(); }
handler_thread.post_message(em);
}
处理程序线程处理它的所有消息并调用act()
,它可以安装自己的try/catch块来处理所有发布的异常。
现在我想知道如果我把这个消息的副本发送给多个接收者会发生什么。一般来说,messages可能有任何数量的收件人,所以我不想对exception propagation消息。exception_ptr
被记录为"共享所有权"智能指针,而rethrow_exception
"不引入数据竞赛"。
所以我的问题是:通过将活动异常存储在exception_ptr
,copy调用指针,并多次调用rethrow_exception
?
根据我对标准的理解,它是合法的。然而,我要注意的是,rethrow不会复制异常,因此,如果您修改共享异常对象并同时从其他线程访问它,共享异常对象本身就会提交给数据竞赛。如果异常是只读的(一旦抛出),那么您应该不会有任何问题。
关于存储时间:
15.1引发异常〔except.sthrow〕
4异常对象的内存以未指定的方式分配,3.7.4.1中指出的除外。如果某个处理程序通过重新引发退出,则控制权将传递给同一异常的另一个处理程序。在异常的最后一个剩余活动处理程序通过除重新抛出之外的任何方式退出后,或者引用异常对象的最后一种类型为
std::exception_ptr
(18.8.5)的对象为销毁,以较晚者为准。在前一种情况下,销毁发生在处理程序退出时,即在销毁处理程序中异常声明中声明的对象(如果有的话)之后。在后一种情况下,破坏发生在std::exception_ptr
的析构函数返回之前。
关于数据竞赛:
18.8.5异常传播[传播]
7为了确定是否存在数据竞争,对
exception_ptr
对象的操作只能访问和修改exception_ptr
对象本身,而不能访问和修改它们引用的异常。对引用同一异常对象的exception_ptr
对象使用rethrow_exception
不应引入数据竞争。[注意:如果rethrow_exception
重新抛出相同的异常对象(而不是副本),则对该重新抛出的异常对象的并发访问可能会引入数据竞争。引用特定异常的exception_ptr
对象数量的变化不会引入数据种族--尾注]
关于rethrow
:
[[noreturn]] void rethrow_exception(exception_ptr p);
9要求:
p
不应为空指针。10抛出:p所指的异常对象。
- 处理多个异常集合的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 时,存在异常处理问题
- 可以通过异常指针"duplicated"异常吗?