unique_ptr 多线程

unique_ptr with multithreading

我有点害怕在没有 mutex 的情况下使用 unique_ptr 多线程。我在下面写了简化代码,请看一下。如果我检查 unique_ptr != nullptr,它是线程安全的吗?

class BigClassCreatedOnce
{
public:
    std::atomic<bool> var;

    // A lot of other stuff
};

BigClassCreatedOnce class 实例只会创建一次,但我不确定在线程之间使用它是否安全。

class MainClass
{
public:
    // m_bigClass used all around the class from the Main Thread

    MainClass()
        : m_bigClass()
        , m_thread()
    {
        m_thread = std::thread([this]() {
            while (1)
            {
                methodToBeCalledFromThread();
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
            }
        });

        // other stuff here

        m_bigClass.reset(new BigClassCreatedOnce()); // created only once
    }

    void methodToBeCalledFromThread()
    {
        if (!m_bigClass) // As I understand this is not safe
        {
            return;
        }

        if (m_bigClass->var.load()) // As I understand this is safe
        {
            // does something
        }
    }

    std::unique_ptr<BigClassCreatedOnce> m_bigClass;
    std::thread m_thread;
};

我只是将它放入无限循环以简化示例。

int main()
{
    MainClass ms;
    while (1)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}

If I check unique_ptr != nullptr, is it thread safe

不,它不是线程安全的。如果您有多个线程,并且其中至少有一个线程写入共享数据,则您需要同步。如果你不这样做,那么你就会发生数据竞争,这是未定义的行为。

m_bigClass.reset(new BigClassCreatedOnce()); // created only once

if (!m_bigClass)

两者可以同时发生,所以这是一场数据竞赛。

我还想指出

if (m_bigClass->var.load())

也不是线程安全的。 var.load() 是,但 m_bigClass 的访问权限不是,所以你也可以在那里进行数据竞争。