c++ - std::exception_ptr 线程安全吗?

标签 c++ exception concurrency thread-safety race-condition

我有一个工作线程,它通过 std::thread 持续运行、创建和管理。在我的工作线程的顶层,我有一个 try/catch block ,里面有一个 while 循环。如果异常泄漏到线程的顶层,我会捕获它并将其存储在 std::exception_ptr 中,它是还拥有非静态线程函数的类的成员:

// In class header (inside class declaration)
std::exception_ptr m_threadException;

// In class CPP file
void MyClass::MyThreadFunction()
{
    try {
        while (true) {
            // Do thread stuff
        }
    }
    catch (std::exception const& e) {
        m_threadException = std::current_exception();
    }
}

一旦线程由于这种异常而死亡,我的类(也主要由主线程使用)还不知道。我的计划是在所有类的主要函数的开头添加线程检查点,如下所示:

void MyClass::SomethingMainThreadCalls()
{
    if (m_threadException) {
        std::rethrow_exception(m_threadException);
        m_threadException = nullptr; // Somehow reset it back to null; not sure if this will work
    }

    // Do normal function stuff
}

假设这是一个好主意,在我的主线程检查 exception_ptr 是否为空(调用 SomethingMainThreadCalls())和工作线程分配给它之间可能存在竞争条件.我还没有找到任何信息(还没有检查 C++11 草案)关于这是否本质上是线程安全的(由标准保证)或者我是否负责这种情况下的线程同步。

如果是后者,使用 std::atomic 是保持简单的好主意吗?示例:

std::atomic<std::exception_ptr> m_threadException;

类似的东西?我对此处有关最佳实践的建议和信息感兴趣。

最佳答案

关于exception_ptr没有特殊说明关于标准中的线程安全性。因此,它提供了默认的标准保证:访问单独的实例没问题,访问相同的实例则不行。

我建议使用 atomic<bool>相反(如果除此之外没有其他原因 exception_ptr 不可平凡复制,因此不能放入 atomic<T> )让其他代码知道 exception_ptr已经设置好了。你会没事的,只要:

  1. 你设置了m_threadException 设置标志之前
  2. 您阅读了 m_threadException 检查标志之后
  3. 您使用适当的加载/存储内存命令来设置/检查标志。默认值没问题
  4. 你只写m_threadException恰好一次。

关于c++ - std::exception_ptr 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41288428/

相关文章:

c++ - 为什么要在实例替换 vector 中删除?

python - 在Tkinter中设置错误处理循环

python - MLFlow 和 Hydra 一起使用会导致崩溃

c++ - 比 C++ 中的异常处理更好的语言特性?

Java future : How to unblock Main thread while executing Aysnc call

C++ JSON 序列化,Proto-buf 风格

c++ - 将头文件包含到头文件中而不将其内容暴露给包含程序

c++ - Boost Asio,异步 UDP 客户端 - 关机时崩溃

ruby - 使用 Ruby(Sinatra?)的并发 Web 请求?

java - 使用 protected block 同步 Hibernate 插入