std :: exception_ptr线程安全吗?

时间:2016-12-22 17:09:48

标签: c++ multithreading c++11

我有一个不断运行,创建和工作的工作线程通过std::thread进行管理。在我的工作线程的顶层,我有一个try / catch块,里面有一个while循环。如果异常泄漏到线程的顶层,我会捕获它并将其存储在std::exception_ptr中,该// In class header (inside class definition) 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
}

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

SomethingMainThreadCalls()

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

如果是后者,正在使用std::atomic<std::exception_ptr> m_threadException; 一个好主意来保持简单?例如:

{{1}}

那样的东西?希望我的问题的答案也包含一些关于最佳实践的好建议和信息。提前谢谢。

3 个答案:

答案 0 :(得分:6)

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

我建议使用atomic<bool>代替atomic<exception_ptr>让其他代码知道已设置exception_ptr。你可以,只要:

  1. 在设置标志
  2. 之前设置m_threadException
  3. 检查标志
  4. 后阅读m_threadException
  5. 使用适当的加载/存储内存顺序来设置/检查标志。默认设置很好
  6. 您只需撰写m_threadException一次。

答案 1 :(得分:2)

标准没有指定std::exception_ptr的实现是什么,因此std::exception_ptr的线程安全性也未指定。

只需用一些锁来包装异常指针,代码就可以了。

答案 2 :(得分:2)

只是尝试执行此操作,但是std::atomic要求可复制的类型,std::exception_ptr不是。您应该像我一样遇到编译错误(使用MSVC VS2019,C ++ 14时)。