std :: exception_ptr线程安全吗?

voi*_*ter 6 c++ multithreading c++11

我有一个工作线程,通过一个不断运行,创建和管理std::thread.在我的工作线程的顶层,我有一个try/catch块,里面有一个while循环.如果异常泄漏到线程的顶层,我会捕获它并将其存储在a中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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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
}
Run Code Online (Sandbox Code Playgroud)

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

如果是后者,使用std::atomic一个好主意来保持简单?例:

std::atomic<std::exception_ptr> m_threadException;
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 6

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

我建议使用atomic<bool>而不是atomic<exception_ptr>让其他代码知道exception_ptr已设置.你会很好,只要:

  1. m_threadException 设置标志之前设置
  2. m_threadException 检查旗帜阅读
  3. 您使用适当的加载/存储内存命令来设置/检查标志.默认设置很好
  4. 你只写m_threadException一次.

  • @ void.pointer:它有一个"文档化的界面".它说[就在网站上](http://en.cppreference.com/w/cpp/error/exception_ptr):"`std :: exception_ptr`符合[NullablePointer]的要求(http:// en. cppreference.com/w/cpp/concept/NullablePointer)." 它甚至说明了默认和复制构造函数的作用.以及比较运营商. (3认同)