这不是关于静态初始化和线程安全的问题。由于C++ 11中使用了该标准中的措辞,因此可以一起保证它们。
到现在为止还挺好。请考虑以下类:

struct S {
    static int id() noexcept {
        static int v = 0;
        return v++;
    }

    template<typename>
    static int value() noexcept {
        static const int v = id();
        return v;
    }
};

在这种情况下,在不同线程上对S::value<MyType>()的两个并发调用是安全的(如果我错了,请纠正我)。

两个并发调用(如S::value<AType>()S::value<AnotherType>())也安全吗?

据我所知,由于专业不同,value本身根本不是问题。但是,当涉及到调用id时,保证第一行(静态初始化)是线程安全的,但是紧随其后的那一行并不适用。
因此,v中的ATypeAnotherType可以具有相同的值。
另一方面,在value中对id进行静态初始化期间会调用v,因此我不确定我期望的有效性。
这就是为什么我问。我的推理是否有问题,或者上面的代码实际上不是线程安全的?

最佳答案

不需要。您必须进行同步,但是在您的情况下,它非常简单:

struct S {
    static int id() noexcept {
        static std::atomic<int> v { 0 };
        return ++v;
    }

    template<typename>
    static int value() noexcept {
        static const int v = id();
        return v;
    }
};

请注意,避免后期增加是一种很好的做法。

关于c++ - 线程安全和静态变量/成员函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49013297/

10-11 22:46
查看更多